|
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); |