Position.js (8190B)
1 /*** 2 3 MochiKit.Position 1.4 4 5 See <http://mochikit.com/> for documentation, downloads, license, etc. 6 7 (c) 2005-2006 Bob Ippolito and others. All rights Reserved. 8 9 ***/ 10 11 if (typeof(dojo) != 'undefined') { 12 dojo.provide('MochiKit.Position'); 13 dojo.require('MochiKit.Base'); 14 dojo.require('MochiKit.DOM'); 15 dojo.require('MochiKit.Style'); 16 } 17 if (typeof(JSAN) != 'undefined') { 18 JSAN.use('MochiKit.Base', []); 19 JSAN.use('MochiKit.DOM', []); 20 JSAN.use('MochiKit.Style', []); 21 } 22 23 try { 24 if (typeof(MochiKit.Base) == 'undefined' || 25 typeof(MochiKit.Style) == 'undefined' || 26 typeof(MochiKit.DOM) == 'undefined') { 27 throw ''; 28 } 29 } catch (e) { 30 throw 'MochiKit.Style depends on MochiKit.Base, MochiKit.DOM, and MochiKit.Style!'; 31 } 32 33 if (typeof(MochiKit.Position) == 'undefined') { 34 MochiKit.Position = {}; 35 } 36 37 MochiKit.Position.NAME = 'MochiKit.Position'; 38 MochiKit.Position.VERSION = '1.4'; 39 MochiKit.Position.__repr__ = function () { 40 return '[' + this.NAME + ' ' + this.VERSION + ']'; 41 }; 42 MochiKit.Position.toString = function () { 43 return this.__repr__(); 44 }; 45 46 MochiKit.Position.EXPORT_OK = []; 47 48 MochiKit.Position.EXPORT = [ 49 ]; 50 51 52 MochiKit.Base.update(MochiKit.Position, { 53 // set to true if needed, warning: firefox performance problems 54 // NOT neeeded for page scrolling, only if draggable contained in 55 // scrollable elements 56 includeScrollOffsets: false, 57 58 /** @id MochiKit.Position.prepare */ 59 prepare: function () { 60 var deltaX = window.pageXOffset 61 || document.documentElement.scrollLeft 62 || document.body.scrollLeft 63 || 0; 64 var deltaY = window.pageYOffset 65 || document.documentElement.scrollTop 66 || document.body.scrollTop 67 || 0; 68 this.windowOffset = new MochiKit.Style.Coordinates(deltaX, deltaY); 69 }, 70 71 /** @id MochiKit.Position.cumulativeOffset */ 72 cumulativeOffset: function (element) { 73 var valueT = 0; 74 var valueL = 0; 75 do { 76 valueT += element.offsetTop || 0; 77 valueL += element.offsetLeft || 0; 78 element = element.offsetParent; 79 } while (element); 80 return new MochiKit.Style.Coordinates(valueL, valueT); 81 }, 82 83 /** @id MochiKit.Position.realOffset */ 84 realOffset: function (element) { 85 var valueT = 0; 86 var valueL = 0; 87 do { 88 valueT += element.scrollTop || 0; 89 valueL += element.scrollLeft || 0; 90 element = element.parentNode; 91 } while (element); 92 return new MochiKit.Style.Coordinates(valueL, valueT); 93 }, 94 95 /** @id MochiKit.Position.within */ 96 within: function (element, x, y) { 97 if (this.includeScrollOffsets) { 98 return this.withinIncludingScrolloffsets(element, x, y); 99 } 100 this.xcomp = x; 101 this.ycomp = y; 102 this.offset = this.cumulativeOffset(element); 103 if (element.style.position == "fixed") { 104 this.offset.x += this.windowOffset.x; 105 this.offset.y += this.windowOffset.y; 106 } 107 108 return (y >= this.offset.y && 109 y < this.offset.y + element.offsetHeight && 110 x >= this.offset.x && 111 x < this.offset.x + element.offsetWidth); 112 }, 113 114 /** @id MochiKit.Position.withinIncludingScrolloffsets */ 115 withinIncludingScrolloffsets: function (element, x, y) { 116 var offsetcache = this.realOffset(element); 117 118 this.xcomp = x + offsetcache.x - this.windowOffset.x; 119 this.ycomp = y + offsetcache.y - this.windowOffset.y; 120 this.offset = this.cumulativeOffset(element); 121 122 return (this.ycomp >= this.offset.y && 123 this.ycomp < this.offset.y + element.offsetHeight && 124 this.xcomp >= this.offset.x && 125 this.xcomp < this.offset.x + element.offsetWidth); 126 }, 127 128 // within must be called directly before 129 /** @id MochiKit.Position.overlap */ 130 overlap: function (mode, element) { 131 if (!mode) { 132 return 0; 133 } 134 if (mode == 'vertical') { 135 return ((this.offset.y + element.offsetHeight) - this.ycomp) / 136 element.offsetHeight; 137 } 138 if (mode == 'horizontal') { 139 return ((this.offset.x + element.offsetWidth) - this.xcomp) / 140 element.offsetWidth; 141 } 142 }, 143 144 /** @id MochiKit.Position.absolutize */ 145 absolutize: function (element) { 146 element = MochiKit.DOM.getElement(element); 147 if (element.style.position == 'absolute') { 148 return; 149 } 150 MochiKit.Position.prepare(); 151 152 var offsets = MochiKit.Position.positionedOffset(element); 153 var width = element.clientWidth; 154 var height = element.clientHeight; 155 156 var oldStyle = { 157 'position': element.style.position, 158 'left': offsets.x - parseFloat(element.style.left || 0), 159 'top': offsets.y - parseFloat(element.style.top || 0), 160 'width': element.style.width, 161 'height': element.style.height 162 }; 163 164 element.style.position = 'absolute'; 165 element.style.top = offsets.y + 'px'; 166 element.style.left = offsets.x + 'px'; 167 element.style.width = width + 'px'; 168 element.style.height = height + 'px'; 169 170 return oldStyle; 171 }, 172 173 /** @id MochiKit.Position.positionedOffset */ 174 positionedOffset: function (element) { 175 var valueT = 0, valueL = 0; 176 do { 177 valueT += element.offsetTop || 0; 178 valueL += element.offsetLeft || 0; 179 element = element.offsetParent; 180 if (element) { 181 p = MochiKit.Style.getStyle(element, 'position'); 182 if (p == 'relative' || p == 'absolute') { 183 break; 184 } 185 } 186 } while (element); 187 return new MochiKit.Style.Coordinates(valueL, valueT); 188 }, 189 190 /** @id MochiKit.Position.relativize */ 191 relativize: function (element, oldPos) { 192 element = MochiKit.DOM.getElement(element); 193 if (element.style.position == 'relative') { 194 return; 195 } 196 MochiKit.Position.prepare(); 197 198 var top = parseFloat(element.style.top || 0) - 199 (oldPos['top'] || 0); 200 var left = parseFloat(element.style.left || 0) - 201 (oldPos['left'] || 0); 202 203 element.style.position = oldPos['position']; 204 element.style.top = top + 'px'; 205 element.style.left = left + 'px'; 206 element.style.width = oldPos['width']; 207 element.style.height = oldPos['height']; 208 }, 209 210 /** @id MochiKit.Position.clone */ 211 clone: function (source, target) { 212 source = MochiKit.DOM.getElement(source); 213 target = MochiKit.DOM.getElement(target); 214 target.style.position = 'absolute'; 215 var offsets = this.cumulativeOffset(source); 216 target.style.top = offsets.y + 'px'; 217 target.style.left = offsets.x + 'px'; 218 target.style.width = source.offsetWidth + 'px'; 219 target.style.height = source.offsetHeight + 'px'; 220 }, 221 222 /** @id MochiKit.Position.page */ 223 page: function (forElement) { 224 var valueT = 0; 225 var valueL = 0; 226 227 var element = forElement; 228 do { 229 valueT += element.offsetTop || 0; 230 valueL += element.offsetLeft || 0; 231 232 // Safari fix 233 if (element.offsetParent == document.body && MochiKit.Style.getStyle(element, 'position') == 'absolute') { 234 break; 235 } 236 } while (element = element.offsetParent); 237 238 element = forElement; 239 do { 240 valueT -= element.scrollTop || 0; 241 valueL -= element.scrollLeft || 0; 242 } while (element = element.parentNode); 243 244 return new MochiKit.Style.Coordinates(valueL, valueT); 245 } 246 }); 247 248 MochiKit.Position.__new__ = function (win) { 249 var m = MochiKit.Base; 250 this.EXPORT_TAGS = { 251 ':common': this.EXPORT, 252 ':all': m.concat(this.EXPORT, this.EXPORT_OK) 253 }; 254 255 m.nameFunctions(this); 256 }; 257 258 MochiKit.Position.__new__(this);