Changeset 9136
- Timestamp:
- 06/14/07 11:25:29 (19 months ago)
- Location:
- dijit/trunk
- Files:
-
- 4 modified
-
tests/test_Tooltip.html (modified) (1 diff)
-
Tooltip.js (modified) (1 diff)
-
util/place.js (modified) (4 diffs)
-
util/popup.js (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
dijit/trunk/tests/test_Tooltip.html
r9096 r9136 40 40 <span id="btnTt" dojoType="dijit.Tooltip" connectId="four" caption="tooltip on button" style="display:none;"></span> 41 41 42 <select id="seven"> 43 <option value="alpha">Alpha</option> 44 <option value="beta">Beta</option> 45 <option value="gamma">Gamma</option> 46 <option value="delta">Delta</option> 47 </select> 48 49 <span dojoType="dijit.Tooltip" connectId="seven" style="display:none;"> 50 tooltip on a select<br> 51 two line tooltip. 42 <span style="float: right"> 43 Test tooltip on right aligned element. Tooltip should flow to the left --> 44 <select id="seven"> 45 <option value="alpha">Alpha</option> 46 <option value="beta">Beta</option> 47 <option value="gamma">Gamma</option> 48 <option value="delta">Delta</option> 49 </select> 50 51 <span dojoType="dijit.Tooltip" connectId="seven" style="display:none;"> 52 tooltip on a select<br> 53 two line tooltip. 54 </span> 52 55 </span> 53 56 -
dijit/trunk/Tooltip.js
r9130 r9136 52 52 // position the element and change CSS according to position 53 53 var align = this.isLeftToRight() ? {'BR': 'BL', 'BL': 'BR'} : {'BL': 'BR', 'BR': 'BL'}; 54 dijit.util.placeOnScreenAroundElement(this.domNode, aroundNode, align); 55 // TODO: need to know which position placeOnScreenAroundElement picked 56 this.domNode.className="dijitTooltip dijitTooltip" + (this.isLeftToRight() ? "Right" : "Left"); 54 var pos = dijit.util.placeOnScreenAroundElement(this.domNode, aroundNode, align); 55 this.domNode.className="dijitTooltip dijitTooltip" + (pos.corner=='BL' ? "Right" : "Left"); 57 56 58 57 // show it -
dijit/trunk/util/place.js
r9133 r9136 42 42 } 43 43 }; 44 // TODO: combine above two functions 44 45 45 46 dijit.util.placeOnScreen = function( 46 47 /* HTMLElement */ node, 47 /* Object */ desiredPos,48 /* Object */ pos, 48 49 /* Object */ corners, 49 50 /* boolean? */ tryOnly){ 50 51 // summary: 51 52 // Keeps 'node' in the visible area of the screen while trying to 52 // place closest to desiredPos.x, desiredPos.y. The input coordinates are53 // place closest to pos.x, pos.y. The input coordinates are 53 54 // expected to be the desired document position. 54 55 // … … 61 62 // and if a perfect match is found, it will be used. Otherwise, it goes through 62 63 // all of the specified corners, and choose the most appropriate one. 63 //64 // If tryOnly is set to true, the node will not be moved to the place.65 64 // 66 65 // NOTE: node is assumed to be absolutely or relatively positioned. 66 67 var choices = dojo.map(corners, function(corner){ return { corner: corner, pos: pos }; }); 68 69 return dijit.util._place(node, choices); 70 } 67 71 68 var scroll = dijit.util.getScroll(); 69 var view = dijit.util.getViewport(); 72 dijit.util._place = function(/*HtmlElement*/ node, /* Array */ choices){ 73 // summary: 74 // Given a list of spots to put node, put it at the first spot where it fits, 75 // of if it doesn't fit anywhere then the place with the least overflow 76 // choices: Array 77 // Array of elements like: {corner: 'TL', pos: {x: 10, y: 20} } 78 // Above example says to put the top-left corner of the node at (10,20) 79 80 // get {x: 10, y: 10, w: 100, h:100} type obj representing position of 81 // viewport over document 82 var view = dojo.mixin(dijit.util.getViewport(), dijit.util.getScroll()); 70 83 71 node = dojo.byId(node); 84 // This won't work if the node is inside a <div style="position: relative">, 85 // so reattach it to document.body. (Otherwise, the positioning will be wrong 86 // and also it might get cutoff) 87 if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){ 88 dojo.body().appendChild(node); 89 } 90 91 // get node margin box size 72 92 var oldDisplay = node.style.display; 73 93 var oldVis = node.style.visibility; 74 94 node.style.visibility = "hidden"; 75 95 node.style.display = ""; 76 // var bb = dojo.html.getBorderBox(node); 77 var bb = dojo.marginBox(node); //PORT okay? 78 var w = bb.w; 79 var h = bb.h; 96 var mb = dojo.marginBox(node); 80 97 node.style.display = oldDisplay; 81 98 node.style.visibility = oldVis; 82 99 83 //#2670 84 var visiblew,visibleh,bestw,besth=""; 100 var best=null; 101 for(var i=0; i<choices.length; i++){ 102 var corner = choices[i].corner; 103 var pos = choices[i].pos; 85 104 86 var bestx, besty, bestDistance = Infinity, bestCorner; 87 88 for(var cidex=0; cidex<corners.length; ++cidex){ 89 var visiblew,visibleh=""; 90 var corner = corners[cidex]; 91 var match = true; 92 93 // guess where to put the upper left corner of the popup, based on which corner was passed 94 // if you choose a corner other than the upper left, 95 // obviously you have to move the popup 96 // so that the selected corner is at the x,y you asked for 97 var tryX = desiredPos.x - (corner.charAt(1)=='L' ? 0 : w) - scroll.x; 98 var tryY = desiredPos.y - (corner.charAt(0)=='T' ? 0 : h) - scroll.y; 99 100 // x component 101 // test if the popup does not fit 102 var x = tryX + w; 103 if(x > view.w){ 104 match = false; 105 // coordinates and size of node with specified corner placed at pos, 106 // and clipped by viewport 107 var startX = (corner.charAt(1)=='L' ? pos.x : Math.max(view.x, pos.x - mb.w)), 108 startY = (corner.charAt(0)=='T' ? pos.y : Math.max(view.y, pos.y - mb.h)), 109 endX = (corner.charAt(1)=='L' ? Math.min(view.x+view.w, startX+mb.w) : pos.x), 110 endY = (corner.charAt(0)=='T' ? Math.min(view.y+view.h, startY+mb.h) : pos.y), 111 width = endX-startX, 112 height = endY-startY, 113 overflow = (mb.w-width) + (mb.h-height); 114 115 if(best==null || overflow<best.overflow){ 116 best = { 117 corner: corner, 118 aroundCorner: choices[i].aroundCorner, 119 x: startX, 120 y: startY, 121 w: width, 122 h: height, 123 overflow: overflow 124 }; 105 125 } 106 // viewport => document 107 // min: left side of screen 108 x = tryX + scroll.x; 109 // calculate the optimal width of the popup 110 if(corner.charAt(1)=='L'){ 111 if(w>view.w-tryX){ 112 visiblew=view.w-tryX; 113 match=false; 114 }else{ 115 visiblew=w; 116 } 117 }else{ 118 if(tryX<0){ 119 visiblew=w+tryX; 120 match=false; 121 }else{ 122 visiblew=w; 123 } 124 } 125 // y component 126 // test if the popup does not fit 127 var y = tryY + h; 128 if(y > view.h){ 129 match = false; 130 } 131 // viewport => document 132 // min: top side of screen 133 y = tryY + scroll.y; 134 // calculate the optimal height of the popup 135 if(corner.charAt(0)=='T'){ 136 if(h>view.h-tryY){ 137 visibleh=view.h-tryY; 138 match=false; 139 }else{ 140 visibleh=h; 141 } 142 }else{ 143 if(tryY<0){ 144 visibleh=h+tryY; 145 match=false; 146 }else{ 147 visibleh=h; 148 } 149 } 150 151 if(match){ //perfect match, return now 152 bestx = x; 153 besty = y; 154 bestDistance = 0; 155 bestw = visiblew; 156 besth = visibleh; 157 bestCorner = corner; 126 if(overflow==0){ 158 127 break; 159 }else{160 //not perfect, find out whether it is better than the saved one161 // weight this position by its squared distance162 var dist = Math.pow(x-tryX-scroll.x,2)+Math.pow(y-tryY-scroll.y,2);163 // if there was not a perfect match but dist=0 anyway (popup too small) weight by size of popup164 if(dist==0){dist=Math.pow(h-visibleh,2);}165 // choose the lightest (closest or biggest popup) position166 if(bestDistance > dist){167 bestDistance = dist;168 bestx = x;169 besty = y;170 bestw = visiblew;171 besth = visibleh;172 bestCorner = corner;173 }174 128 } 175 129 } 176 130 177 if(!tryOnly){ 178 node.style.left = bestx + "px"; 179 node.style.top = besty + "px"; 180 } 181 182 return {left: bestx, top: besty, x: bestx, y: besty, dist: bestDistance, corner: bestCorner, h:besth, w:bestw}; // object 131 node.style.left = best.x + "px"; 132 node.style.top = best.y + "px"; 133 return best; 183 134 } 184 135 … … 197 148 // corners parameter in dijit.util.placeOnScreen) 198 149 // e.g. {'TL': 'BL', 'BL': 'TL'} 199 200 // This won't work if the node is inside a <div style="position: relative">, 201 // so reattach it to document.body. (Otherwise, the positioning will be wrong 202 // and also it might get cutoff) 203 if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){ 204 dojo.body().appendChild(node); 205 } 206 207 var best, bestDistance=Infinity; 150 151 // get coordinates of aroundNode 208 152 aroundNode = dojo.byId(aroundNode); 209 153 var oldDisplay = aroundNode.style.display; 210 154 aroundNode.style.display=""; 211 155 // #3172: use the slightly tighter border box instead of marginBox 212 //var mb = dojo.marginBox(aroundNode);213 //aroundNode.style.borderWidth="10px";214 156 var aroundNodeW = aroundNode.offsetWidth; //mb.w; 215 157 var aroundNodeH = aroundNode.offsetHeight; //mb.h; … … 217 159 aroundNode.style.display=oldDisplay; 218 160 161 // Generate list of possible positions for node 162 var choices = []; 219 163 for(var nodeCorner in aroundCorners){ 220 var corners = aroundCorners[nodeCorner]; 221 222 var desiredPos = { 223 x: aroundNodePos.x + (nodeCorner.charAt(1)=='L' ? 0 : aroundNodeW), 224 y: aroundNodePos.y + (nodeCorner.charAt(0)=='T' ? 0 : aroundNodeH) 225 }; 226 227 var pos = dijit.util.placeOnScreen(node, desiredPos, [corners], true); 228 if(pos.dist == 0){ 229 best = pos; 230 break; 231 }else{ 232 //not perfect, find out whether it is better than the saved one 233 if(bestDistance > pos.dist){ 234 bestDistance = pos.dist; 235 best = pos; 164 choices.push( { 165 aroundCorner: nodeCorner, 166 corner: aroundCorners[nodeCorner], 167 pos: { 168 x: aroundNodePos.x + (nodeCorner.charAt(1)=='L' ? 0 : aroundNodeW), 169 y: aroundNodePos.y + (nodeCorner.charAt(0)=='T' ? 0 : aroundNodeH) 236 170 } 237 } 171 }); 238 172 } 239 240 node.style.left = best.left + "px"; 241 node.style.top = best.top + "px"; 242 243 return best; // object 173 174 return dijit.util._place(node, choices); 244 175 } -
dijit/trunk/util/popup.js
r9133 r9136 70 70 var best = args.around ? 71 71 dijit.util.placeOnScreenAroundElement(wrapper, args.around, args.orient) : 72 dijit.util.placeOnScreen(wrapper, args, ['TL','BL',' BL','BR']);72 dijit.util.placeOnScreen(wrapper, args, ['TL','BL','TR','BR']); 73 73 74 74 // TODO: use effects to fade in wrapper