|
1 |
|
2 MochiKit.Base.update(MochiKit.DOM, { |
|
3 /** @id MochiKit.DOM.makeClipping */ |
|
4 makeClipping: function (element) { |
|
5 element = MochiKit.DOM.getElement(element); |
|
6 var oldOverflow = element.style.overflow; |
|
7 if ((MochiKit.Style.getStyle(element, 'overflow') || 'visible') != 'hidden') { |
|
8 element.style.overflow = 'hidden'; |
|
9 } |
|
10 return oldOverflow; |
|
11 }, |
|
12 |
|
13 /** @id MochiKit.DOM.undoClipping */ |
|
14 undoClipping: function (element, overflow) { |
|
15 element = MochiKit.DOM.getElement(element); |
|
16 if (!overflow) { |
|
17 return; |
|
18 } |
|
19 element.style.overflow = overflow; |
|
20 }, |
|
21 |
|
22 /** @id MochiKit.DOM.makePositioned */ |
|
23 makePositioned: function (element) { |
|
24 element = MochiKit.DOM.getElement(element); |
|
25 var pos = MochiKit.Style.getStyle(element, 'position'); |
|
26 if (pos == 'static' || !pos) { |
|
27 element.style.position = 'relative'; |
|
28 // Opera returns the offset relative to the positioning context, |
|
29 // when an element is position relative but top and left have |
|
30 // not been defined |
|
31 if (/Opera/.test(navigator.userAgent)) { |
|
32 element.style.top = 0; |
|
33 element.style.left = 0; |
|
34 } |
|
35 } |
|
36 }, |
|
37 |
|
38 /** @id MochiKit.DOM.undoPositioned */ |
|
39 undoPositioned: function (element) { |
|
40 element = MochiKit.DOM.getElement(element); |
|
41 if (element.style.position == 'relative') { |
|
42 element.style.position = element.style.top = element.style.left = element.style.bottom = element.style.right = ''; |
|
43 } |
|
44 }, |
|
45 |
|
46 /** @id MochiKit.DOM.getFirstElementByTagAndClassName */ |
|
47 getFirstElementByTagAndClassName: function (tagName, className, |
|
48 /* optional */parent) { |
|
49 var self = MochiKit.DOM; |
|
50 if (typeof(tagName) == 'undefined' || tagName === null) { |
|
51 tagName = '*'; |
|
52 } |
|
53 if (typeof(parent) == 'undefined' || parent === null) { |
|
54 parent = self._document; |
|
55 } |
|
56 parent = self.getElement(parent); |
|
57 var children = (parent.getElementsByTagName(tagName) |
|
58 || self._document.all); |
|
59 if (typeof(className) == 'undefined' || className === null) { |
|
60 return children[0]; |
|
61 } |
|
62 |
|
63 for (var i = 0; i < children.length; i++) { |
|
64 var child = children[i]; |
|
65 var classNames = child.className.split(' '); |
|
66 for (var j = 0; j < classNames.length; j++) { |
|
67 if (classNames[j] == className) { |
|
68 return child; |
|
69 } |
|
70 } |
|
71 } |
|
72 }, |
|
73 |
|
74 /** @id MochiKit.DOM.isParent */ |
|
75 isParent: function (child, element) { |
|
76 if (!child.parentNode || child == element) { |
|
77 return false; |
|
78 } |
|
79 |
|
80 if (child.parentNode == element) { |
|
81 return true; |
|
82 } |
|
83 |
|
84 return MochiKit.DOM.isParent(child.parentNode, element); |
|
85 } |
|
86 }); |
|
87 |
|
88 MochiKit.Position = { |
|
89 // set to true if needed, warning: firefox performance problems |
|
90 // NOT neeeded for page scrolling, only if draggable contained in |
|
91 // scrollable elements |
|
92 includeScrollOffsets: false, |
|
93 |
|
94 /** @id MochiKit.Position.prepare */ |
|
95 prepare: function () { |
|
96 var deltaX = window.pageXOffset |
|
97 || document.documentElement.scrollLeft |
|
98 || document.body.scrollLeft |
|
99 || 0; |
|
100 var deltaY = window.pageYOffset |
|
101 || document.documentElement.scrollTop |
|
102 || document.body.scrollTop |
|
103 || 0; |
|
104 this.windowOffset = new MochiKit.Style.Coordinates(deltaX, deltaY); |
|
105 }, |
|
106 |
|
107 /** @id MochiKit.Position.cumulativeOffset */ |
|
108 cumulativeOffset: function (element) { |
|
109 var valueT = 0; |
|
110 var valueL = 0; |
|
111 do { |
|
112 valueT += element.offsetTop || 0; |
|
113 valueL += element.offsetLeft || 0; |
|
114 element = element.offsetParent; |
|
115 } while (element); |
|
116 return new MochiKit.Style.Coordinates(valueL, valueT); |
|
117 }, |
|
118 |
|
119 /** @id MochiKit.Position.realOffset */ |
|
120 realOffset: function (element) { |
|
121 var valueT = 0; |
|
122 var valueL = 0; |
|
123 do { |
|
124 valueT += element.scrollTop || 0; |
|
125 valueL += element.scrollLeft || 0; |
|
126 element = element.parentNode; |
|
127 } while (element); |
|
128 return new MochiKit.Style.Coordinates(valueL, valueT); |
|
129 }, |
|
130 |
|
131 /** @id MochiKit.Position.within */ |
|
132 within: function (element, x, y) { |
|
133 if (this.includeScrollOffsets) { |
|
134 return this.withinIncludingScrolloffsets(element, x, y); |
|
135 } |
|
136 this.xcomp = x; |
|
137 this.ycomp = y; |
|
138 this.offset = this.cumulativeOffset(element); |
|
139 if (element.style.position == "fixed") { |
|
140 this.offset.x += this.windowOffset.x; |
|
141 this.offset.y += this.windowOffset.y; |
|
142 } |
|
143 |
|
144 return (y >= this.offset.y && |
|
145 y < this.offset.y + element.offsetHeight && |
|
146 x >= this.offset.x && |
|
147 x < this.offset.x + element.offsetWidth); |
|
148 }, |
|
149 |
|
150 /** @id MochiKit.Position.withinIncludingScrolloffsets */ |
|
151 withinIncludingScrolloffsets: function (element, x, y) { |
|
152 var offsetcache = this.realOffset(element); |
|
153 |
|
154 this.xcomp = x + offsetcache.x - this.windowOffset.x; |
|
155 this.ycomp = y + offsetcache.y - this.windowOffset.y; |
|
156 this.offset = this.cumulativeOffset(element); |
|
157 |
|
158 return (this.ycomp >= this.offset.y && |
|
159 this.ycomp < this.offset.y + element.offsetHeight && |
|
160 this.xcomp >= this.offset.x && |
|
161 this.xcomp < this.offset.x + element.offsetWidth); |
|
162 }, |
|
163 |
|
164 // within must be called directly before |
|
165 /** @id MochiKit.Position.overlap */ |
|
166 overlap: function (mode, element) { |
|
167 if (!mode) { |
|
168 return 0; |
|
169 } |
|
170 if (mode == 'vertical') { |
|
171 return ((this.offset.y + element.offsetHeight) - this.ycomp) / |
|
172 element.offsetHeight; |
|
173 } |
|
174 if (mode == 'horizontal') { |
|
175 return ((this.offset.x + element.offsetWidth) - this.xcomp) / |
|
176 element.offsetWidth; |
|
177 } |
|
178 }, |
|
179 |
|
180 /** @id MochiKit.Position.absolutize */ |
|
181 absolutize: function (element) { |
|
182 element = MochiKit.DOM.getElement(element); |
|
183 if (element.style.position == 'absolute') { |
|
184 return; |
|
185 } |
|
186 MochiKit.Position.prepare(); |
|
187 |
|
188 var offsets = MochiKit.Position.positionedOffset(element); |
|
189 var width = element.clientWidth; |
|
190 var height = element.clientHeight; |
|
191 |
|
192 var oldStyle = { |
|
193 'position': element.style.position, |
|
194 'left': offsets.x - parseFloat(element.style.left || 0), |
|
195 'top': offsets.y - parseFloat(element.style.top || 0), |
|
196 'width': element.style.width, |
|
197 'height': element.style.height |
|
198 }; |
|
199 |
|
200 element.style.position = 'absolute'; |
|
201 element.style.top = offsets.y + 'px'; |
|
202 element.style.left = offsets.x + 'px'; |
|
203 element.style.width = width + 'px'; |
|
204 element.style.height = height + 'px'; |
|
205 |
|
206 return oldStyle; |
|
207 }, |
|
208 |
|
209 /** @id MochiKit.Position.positionedOffset */ |
|
210 positionedOffset: function (element) { |
|
211 var valueT = 0, valueL = 0; |
|
212 do { |
|
213 valueT += element.offsetTop || 0; |
|
214 valueL += element.offsetLeft || 0; |
|
215 element = element.offsetParent; |
|
216 if (element) { |
|
217 p = MochiKit.Style.getStyle(element, 'position'); |
|
218 if (p == 'relative' || p == 'absolute') { |
|
219 break; |
|
220 } |
|
221 } |
|
222 } while (element); |
|
223 return new MochiKit.Style.Coordinates(valueL, valueT); |
|
224 }, |
|
225 |
|
226 /** @id MochiKit.Position.relativize */ |
|
227 relativize: function (element, oldPos) { |
|
228 element = MochiKit.DOM.getElement(element); |
|
229 if (element.style.position == 'relative') { |
|
230 return; |
|
231 } |
|
232 MochiKit.Position.prepare(); |
|
233 |
|
234 var top = parseFloat(element.style.top || 0) - |
|
235 (oldPos['top'] || 0); |
|
236 var left = parseFloat(element.style.left || 0) - |
|
237 (oldPos['left'] || 0); |
|
238 |
|
239 element.style.position = oldPos['position']; |
|
240 element.style.top = top + 'px'; |
|
241 element.style.left = left + 'px'; |
|
242 element.style.width = oldPos['width']; |
|
243 element.style.height = oldPos['height']; |
|
244 }, |
|
245 |
|
246 /** @id MochiKit.Position.clone */ |
|
247 clone: function (source, target) { |
|
248 source = MochiKit.DOM.getElement(source); |
|
249 target = MochiKit.DOM.getElement(target); |
|
250 target.style.position = 'absolute'; |
|
251 var offsets = this.cumulativeOffset(source); |
|
252 target.style.top = offsets.y + 'px'; |
|
253 target.style.left = offsets.x + 'px'; |
|
254 target.style.width = source.offsetWidth + 'px'; |
|
255 target.style.height = source.offsetHeight + 'px'; |
|
256 }, |
|
257 |
|
258 /** @id MochiKit.Position.page */ |
|
259 page: function (forElement) { |
|
260 var valueT = 0; |
|
261 var valueL = 0; |
|
262 |
|
263 var element = forElement; |
|
264 do { |
|
265 valueT += element.offsetTop || 0; |
|
266 valueL += element.offsetLeft || 0; |
|
267 |
|
268 // Safari fix |
|
269 if (element.offsetParent == document.body && MochiKit.Style.getStyle(element, 'position') == 'absolute') { |
|
270 break; |
|
271 } |
|
272 } while (element = element.offsetParent); |
|
273 |
|
274 element = forElement; |
|
275 do { |
|
276 valueT -= element.scrollTop || 0; |
|
277 valueL -= element.scrollLeft || 0; |
|
278 } while (element = element.parentNode); |
|
279 |
|
280 return new MochiKit.Style.Coordinates(valueL, valueT); |
|
281 } |
|
282 }; |
|
283 |