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';
13 /** @id MochiKit.DOM.undoClipping */
14 undoClipping: function (element
, overflow
) {
15 element
= MochiKit
.DOM
.getElement(element
);
19 element
.style
.overflow
= overflow
;
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
31 if (/Opera/.test(navigator
.userAgent
)) {
32 element
.style
.top
= 0;
33 element
.style
.left
= 0;
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
= '';
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) {
53 if (typeof(parent
) == 'undefined' || parent
=== null) {
54 parent
= self
._document
;
56 parent
= self
.getElement(parent
);
57 var children
= (parent
.getElementsByTagName(tagName
)
58 || self
._document
.all
);
59 if (typeof(className
) == 'undefined' || className
=== null) {
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
) {
74 /** @id MochiKit.DOM.isParent */
75 isParent: function (child
, element
) {
76 if (!child
.parentNode
|| child
== element
) {
80 if (child
.parentNode
== element
) {
84 return MochiKit
.DOM
.isParent(child
.parentNode
, element
);
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,
94 /** @id MochiKit.Position.prepare */
95 prepare: function () {
96 var deltaX
= window
.pageXOffset
97 || document
.documentElement
.scrollLeft
98 || document
.body
.scrollLeft
100 var deltaY
= window
.pageYOffset
101 || document
.documentElement
.scrollTop
102 || document
.body
.scrollTop
104 this.windowOffset
= new MochiKit
.Style
.Coordinates(deltaX
, deltaY
);
107 /** @id MochiKit.Position.cumulativeOffset */
108 cumulativeOffset: function (element
) {
112 valueT
+= element
.offsetTop
|| 0;
113 valueL
+= element
.offsetLeft
|| 0;
114 element
= element
.offsetParent
;
116 return new MochiKit
.Style
.Coordinates(valueL
, valueT
);
119 /** @id MochiKit.Position.realOffset */
120 realOffset: function (element
) {
124 valueT
+= element
.scrollTop
|| 0;
125 valueL
+= element
.scrollLeft
|| 0;
126 element
= element
.parentNode
;
128 return new MochiKit
.Style
.Coordinates(valueL
, valueT
);
131 /** @id MochiKit.Position.within */
132 within: function (element
, x
, y
) {
133 if (this.includeScrollOffsets
) {
134 return this.withinIncludingScrolloffsets(element
, x
, 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
;
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
);
150 /** @id MochiKit.Position.withinIncludingScrolloffsets */
151 withinIncludingScrolloffsets: function (element
, x
, y
) {
152 var offsetcache
= this.realOffset(element
);
154 this.xcomp
= x
+ offsetcache
.x
- this.windowOffset
.x
;
155 this.ycomp
= y
+ offsetcache
.y
- this.windowOffset
.y
;
156 this.offset
= this.cumulativeOffset(element
);
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
);
164 // within must be called directly before
165 /** @id MochiKit.Position.overlap */
166 overlap: function (mode
, element
) {
170 if (mode
== 'vertical') {
171 return ((this.offset
.y
+ element
.offsetHeight
) - this.ycomp
) /
172 element
.offsetHeight
;
174 if (mode
== 'horizontal') {
175 return ((this.offset
.x
+ element
.offsetWidth
) - this.xcomp
) /
180 /** @id MochiKit.Position.absolutize */
181 absolutize: function (element
) {
182 element
= MochiKit
.DOM
.getElement(element
);
183 if (element
.style
.position
== 'absolute') {
186 MochiKit
.Position
.prepare();
188 var offsets
= MochiKit
.Position
.positionedOffset(element
);
189 var width
= element
.clientWidth
;
190 var height
= element
.clientHeight
;
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
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';
209 /** @id MochiKit.Position.positionedOffset */
210 positionedOffset: function (element
) {
211 var valueT
= 0, valueL
= 0;
213 valueT
+= element
.offsetTop
|| 0;
214 valueL
+= element
.offsetLeft
|| 0;
215 element
= element
.offsetParent
;
217 p
= MochiKit
.Style
.getStyle(element
, 'position');
218 if (p
== 'relative' || p
== 'absolute') {
223 return new MochiKit
.Style
.Coordinates(valueL
, valueT
);
226 /** @id MochiKit.Position.relativize */
227 relativize: function (element
, oldPos
) {
228 element
= MochiKit
.DOM
.getElement(element
);
229 if (element
.style
.position
== 'relative') {
232 MochiKit
.Position
.prepare();
234 var top
= parseFloat(element
.style
.top
|| 0) -
235 (oldPos
['top'] || 0);
236 var left
= parseFloat(element
.style
.left
|| 0) -
237 (oldPos
['left'] || 0);
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'];
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';
258 /** @id MochiKit.Position.page */
259 page: function (forElement
) {
263 var element
= forElement
;
265 valueT
+= element
.offsetTop
|| 0;
266 valueL
+= element
.offsetLeft
|| 0;
269 if (element
.offsetParent
== document
.body
&& MochiKit
.Style
.getStyle(element
, 'position') == 'absolute') {
272 } while (element
= element
.offsetParent
);
274 element
= forElement
;
276 valueT
-= element
.scrollTop
|| 0;
277 valueL
-= element
.scrollLeft
|| 0;
278 } while (element
= element
.parentNode
);
280 return new MochiKit
.Style
.Coordinates(valueL
, valueT
);