Commit | Line | Data |
---|---|---|
6a1aa64f DV |
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); |