]> git.pond.sub.org Git - eow/blob - 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
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");
4
5 // ported from dojo.html.util
6
7 dijit.getViewport = function(){
8         //      summary
9         //      Returns the dimensions and scroll position of the viewable area of a browser window
10
11         var _window = dojo.global;
12         var _document = dojo.doc;
13
14         // get viewport size
15         var w = 0, h = 0;
16         var de = _document.documentElement;
17         var dew = de.clientWidth, deh = de.clientHeight;
18         if(dojo.isMozilla){
19                 // mozilla
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;
26                 if(dbw > dew){
27                         minw = dew;
28                         maxw = dbw;
29                 }else{
30                         maxw = dew;
31                         minw = dbw;
32                 }
33                 var dbh = _document.body.clientHeight;
34                 if(dbh > deh){
35                         minh = deh;
36                         maxh = dbh;
37                 }else{
38                         maxh = deh;
39                         minh = dbh;
40                 }
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){
50                 w = dew;
51                 h = deh;
52         }else if(dojo.body().clientWidth){
53                 // IE5, Opera
54                 w = dojo.body().clientWidth;
55                 h = dojo.body().clientHeight;
56         }
57
58         // get scroll position
59         var scroll = dojo._docScroll();
60
61         return { w: w, h: h, l: scroll.x, t: scroll.y };        //      object
62 };
63
64 dijit.placeOnScreen = function(
65         /* DomNode */   node,
66         /* Object */            pos,
67         /* Object */            corners,
68         /* boolean? */          tryOnly){
69         //      summary:
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.
73         //
74         //              Set which corner(s) you want to bind to, such as
75         //              
76         //                      placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"])
77         //              
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.
82         //              
83         //              NOTE: node is assumed to be absolutely or relatively positioned.
84
85         var choices = dojo.map(corners, function(corner){ return { corner: corner, pos: pos }; });
86
87         return dijit._place(node, choices);
88 }
89
90 dijit._place = function(/*DomNode*/ node, /* Array */ choices, /* Function */ layoutNode){
91         // summary:
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
94         // choices: Array
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.
100
101         // get {x: 10, y: 10, w: 100, h:100} type obj representing position of
102         // viewport over document
103         var view = dijit.getViewport();
104
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);
110         }
111
112         var best = null;
113         dojo.some(choices, function(choice){
114                 var corner = choice.corner;
115                 var pos = choice.pos;
116
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)
120                 if(layoutNode){
121                         layoutNode(node, choice.aroundCorner, corner);
122                 }
123
124                 // get node's size
125                 var style = node.style;
126                 var oldDisplay = style.display;
127                 var oldVis = style.visibility;
128                 style.visibility = "hidden";
129                 style.display = "";
130                 var mb = dojo.marginBox(node);
131                 style.display = oldDisplay;
132                 style.visibility = oldVis;
133
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);
143
144                 if(best == null || overflow < best.overflow){
145                         best = {
146                                 corner: corner,
147                                 aroundCorner: choice.aroundCorner,
148                                 x: startX,
149                                 y: startY,
150                                 w: width,
151                                 h: height,
152                                 overflow: overflow
153                         };
154                 }
155                 return !overflow;
156         });
157
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);
162         }
163         return best;
164 }
165
166 dijit.placeOnScreenAroundElement = function(
167         /* DomNode */           node,
168         /* DomNode */           aroundNode,
169         /* Object */            aroundCorners,
170         /* Function */          layoutNode){
171
172         //      summary
173         //      Like placeOnScreen, except it accepts aroundNode instead of x,y
174         //      and attempts to place node around it.  Uses margin box dimensions.
175         //
176         //      aroundCorners
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'}
181         //
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.
185
186
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;
196
197         // Generate list of possible positions for node
198         var choices = [];
199         for(var nodeCorner in aroundCorners){
200                 choices.push( {
201                         aroundCorner: nodeCorner,
202                         corner: aroundCorners[nodeCorner],
203                         pos: {
204                                 x: aroundNodePos.x + (nodeCorner.charAt(1) == 'L' ? 0 : aroundNodeW),
205                                 y: aroundNodePos.y + (nodeCorner.charAt(0) == 'T' ? 0 : aroundNodeH)
206                         }
207                 });
208         }
209
210         return dijit._place(node, choices, layoutNode);
211 }
212
213 }