1 if(!dojo._hasResource["dijit._base.place"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dijit._base.place"] = true;
3 dojo.provide("dijit._base.place");
5 // ported from dojo.html.util
7 dijit.getViewport = function(){
9 // Returns the dimensions and scroll position of the viewable area of a browser window
11 var _window = dojo.global;
12 var _document = dojo.doc;
16 var de = _document.documentElement;
17 var dew = de.clientWidth, deh = de.clientHeight;
20 // _window.innerHeight includes the height taken by the scroll bar
21 // clientHeight is ideal but has DTD issues:
22 // #4539: FF reverses the roles of body.clientHeight/Width and documentElement.clientHeight/Width based on the DTD!
23 // check DTD to see whether body or documentElement returns the viewport dimensions using this algorithm:
24 var minw, minh, maxw, maxh;
25 var dbw = _document.body.clientWidth;
33 var dbh = _document.body.clientHeight;
41 w = (maxw > _window.innerWidth) ? minw : maxw;
42 h = (maxh > _window.innerHeight) ? minh : maxh;
43 }else if(!dojo.isOpera && _window.innerWidth){
44 //in opera9, dojo.body().clientWidth should be used, instead
45 //of window.innerWidth/document.documentElement.clientWidth
46 //so we have to check whether it is opera
47 w = _window.innerWidth;
48 h = _window.innerHeight;
49 }else if(dojo.isIE && de && deh){
52 }else if(dojo.body().clientWidth){
54 w = dojo.body().clientWidth;
55 h = dojo.body().clientHeight;
58 // get scroll position
59 var scroll = dojo._docScroll();
61 return { w: w, h: h, l: scroll.x, t: scroll.y }; // object
64 dijit.placeOnScreen = function(
68 /* boolean? */ tryOnly){
70 // Keeps 'node' in the visible area of the screen while trying to
71 // place closest to pos.x, pos.y. The input coordinates are
72 // expected to be the desired document position.
74 // Set which corner(s) you want to bind to, such as
76 // placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"])
78 // The desired x/y will be treated as the topleft(TL)/topright(TR) or
79 // BottomLeft(BL)/BottomRight(BR) corner of the node. Each corner is tested
80 // and if a perfect match is found, it will be used. Otherwise, it goes through
81 // all of the specified corners, and choose the most appropriate one.
83 // NOTE: node is assumed to be absolutely or relatively positioned.
85 var choices = dojo.map(corners, function(corner){ return { corner: corner, pos: pos }; });
87 return dijit._place(node, choices);
90 dijit._place = function(/*DomNode*/ node, /* Array */ choices, /* Function */ layoutNode){
92 // Given a list of spots to put node, put it at the first spot where it fits,
93 // of if it doesn't fit anywhere then the place with the least overflow
95 // Array of elements like: {corner: 'TL', pos: {x: 10, y: 20} }
96 // Above example says to put the top-left corner of the node at (10,20)
97 // layoutNode: Function(node, aroundNodeCorner, nodeCorner)
98 // for things like tooltip, they are displayed differently (and have different dimensions)
99 // based on their orientation relative to the parent. This adjusts the popup based on orientation.
101 // get {x: 10, y: 10, w: 100, h:100} type obj representing position of
102 // viewport over document
103 var view = dijit.getViewport();
105 // This won't work if the node is inside a <div style="position: relative">,
106 // so reattach it to dojo.doc.body. (Otherwise, the positioning will be wrong
107 // and also it might get cutoff)
108 if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){
109 dojo.body().appendChild(node);
113 dojo.some(choices, function(choice){
114 var corner = choice.corner;
115 var pos = choice.pos;
117 // configure node to be displayed in given position relative to button
118 // (need to do this in order to get an accurate size for the node, because
119 // a tooltips size changes based on position, due to triangle)
121 layoutNode(node, choice.aroundCorner, corner);
125 var style = node.style;
126 var oldDisplay = style.display;
127 var oldVis = style.visibility;
128 style.visibility = "hidden";
130 var mb = dojo.marginBox(node);
131 style.display = oldDisplay;
132 style.visibility = oldVis;
134 // coordinates and size of node with specified corner placed at pos,
135 // and clipped by viewport
136 var startX = (corner.charAt(1) == 'L' ? pos.x : Math.max(view.l, pos.x - mb.w)),
137 startY = (corner.charAt(0) == 'T' ? pos.y : Math.max(view.t, pos.y - mb.h)),
138 endX = (corner.charAt(1) == 'L' ? Math.min(view.l + view.w, startX + mb.w) : pos.x),
139 endY = (corner.charAt(0) == 'T' ? Math.min(view.t + view.h, startY + mb.h) : pos.y),
140 width = endX - startX,
141 height = endY - startY,
142 overflow = (mb.w - width) + (mb.h - height);
144 if(best == null || overflow < best.overflow){
147 aroundCorner: choice.aroundCorner,
158 node.style.left = best.x + "px";
159 node.style.top = best.y + "px";
160 if(best.overflow && layoutNode){
161 layoutNode(node, best.aroundCorner, best.corner);
166 dijit.placeOnScreenAroundElement = function(
168 /* DomNode */ aroundNode,
169 /* Object */ aroundCorners,
170 /* Function */ layoutNode){
173 // Like placeOnScreen, except it accepts aroundNode instead of x,y
174 // and attempts to place node around it. Uses margin box dimensions.
177 // specify Which corner of aroundNode should be
178 // used to place the node => which corner(s) of node to use (see the
179 // corners parameter in dijit.placeOnScreen)
180 // e.g. {'TL': 'BL', 'BL': 'TL'}
182 // layoutNode: Function(node, aroundNodeCorner, nodeCorner)
183 // for things like tooltip, they are displayed differently (and have different dimensions)
184 // based on their orientation relative to the parent. This adjusts the popup based on orientation.
187 // get coordinates of aroundNode
188 aroundNode = dojo.byId(aroundNode);
189 var oldDisplay = aroundNode.style.display;
190 aroundNode.style.display="";
191 // #3172: use the slightly tighter border box instead of marginBox
192 var aroundNodeW = aroundNode.offsetWidth; //mb.w;
193 var aroundNodeH = aroundNode.offsetHeight; //mb.h;
194 var aroundNodePos = dojo.coords(aroundNode, true);
195 aroundNode.style.display=oldDisplay;
197 // Generate list of possible positions for node
199 for(var nodeCorner in aroundCorners){
201 aroundCorner: nodeCorner,
202 corner: aroundCorners[nodeCorner],
204 x: aroundNodePos.x + (nodeCorner.charAt(1) == 'L' ? 0 : aroundNodeW),
205 y: aroundNodePos.y + (nodeCorner.charAt(0) == 'T' ? 0 : aroundNodeH)
210 return dijit._place(node, choices, layoutNode);