5 See <http://mochikit.com/> for documentation, downloads, license, etc.
7 (c) 2005-2006 Bob Ippolito and others. All rights Reserved.
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');
17 if (typeof(JSAN
) != 'undefined') {
18 JSAN
.use('MochiKit.Base', []);
19 JSAN
.use('MochiKit.DOM', []);
20 JSAN
.use('MochiKit.Style', []);
24 if (typeof(MochiKit
.Base
) == 'undefined' ||
25 typeof(MochiKit
.Style
) == 'undefined' ||
26 typeof(MochiKit
.DOM
) == 'undefined') {
30 throw 'MochiKit.Style depends on MochiKit.Base, MochiKit.DOM, and MochiKit.Style!';
33 if (typeof(MochiKit
.Position
) == 'undefined') {
34 MochiKit
.Position
= {};
37 MochiKit
.Position
.NAME
= 'MochiKit.Position';
38 MochiKit
.Position
.VERSION
= '1.4';
39 MochiKit
.Position
.__repr__ = function () {
40 return '[' + this.NAME
+ ' ' + this.VERSION
+ ']';
42 MochiKit
.Position
.toString = function () {
43 return this.__repr__();
46 MochiKit
.Position
.EXPORT_OK
= [];
48 MochiKit
.Position
.EXPORT
= [
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,
58 /** @id MochiKit.Position.prepare */
59 prepare: function () {
60 var deltaX
= window
.pageXOffset
61 || document
.documentElement
.scrollLeft
62 || document
.body
.scrollLeft
64 var deltaY
= window
.pageYOffset
65 || document
.documentElement
.scrollTop
66 || document
.body
.scrollTop
68 this.windowOffset
= new MochiKit
.Style
.Coordinates(deltaX
, deltaY
);
71 /** @id MochiKit.Position.cumulativeOffset */
72 cumulativeOffset: function (element
) {
76 valueT
+= element
.offsetTop
|| 0;
77 valueL
+= element
.offsetLeft
|| 0;
78 element
= element
.offsetParent
;
80 return new MochiKit
.Style
.Coordinates(valueL
, valueT
);
83 /** @id MochiKit.Position.realOffset */
84 realOffset: function (element
) {
88 valueT
+= element
.scrollTop
|| 0;
89 valueL
+= element
.scrollLeft
|| 0;
90 element
= element
.parentNode
;
92 return new MochiKit
.Style
.Coordinates(valueL
, valueT
);
95 /** @id MochiKit.Position.within */
96 within: function (element
, x
, y
) {
97 if (this.includeScrollOffsets
) {
98 return this.withinIncludingScrolloffsets(element
, x
, 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
;
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
);
114 /** @id MochiKit.Position.withinIncludingScrolloffsets */
115 withinIncludingScrolloffsets: function (element
, x
, y
) {
116 var offsetcache
= this.realOffset(element
);
118 this.xcomp
= x
+ offsetcache
.x
- this.windowOffset
.x
;
119 this.ycomp
= y
+ offsetcache
.y
- this.windowOffset
.y
;
120 this.offset
= this.cumulativeOffset(element
);
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
);
128 // within must be called directly before
129 /** @id MochiKit.Position.overlap */
130 overlap: function (mode
, element
) {
134 if (mode
== 'vertical') {
135 return ((this.offset
.y
+ element
.offsetHeight
) - this.ycomp
) /
136 element
.offsetHeight
;
138 if (mode
== 'horizontal') {
139 return ((this.offset
.x
+ element
.offsetWidth
) - this.xcomp
) /
144 /** @id MochiKit.Position.absolutize */
145 absolutize: function (element
) {
146 element
= MochiKit
.DOM
.getElement(element
);
147 if (element
.style
.position
== 'absolute') {
150 MochiKit
.Position
.prepare();
152 var offsets
= MochiKit
.Position
.positionedOffset(element
);
153 var width
= element
.clientWidth
;
154 var height
= element
.clientHeight
;
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
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';
173 /** @id MochiKit.Position.positionedOffset */
174 positionedOffset: function (element
) {
175 var valueT
= 0, valueL
= 0;
177 valueT
+= element
.offsetTop
|| 0;
178 valueL
+= element
.offsetLeft
|| 0;
179 element
= element
.offsetParent
;
181 p
= MochiKit
.Style
.getStyle(element
, 'position');
182 if (p
== 'relative' || p
== 'absolute') {
187 return new MochiKit
.Style
.Coordinates(valueL
, valueT
);
190 /** @id MochiKit.Position.relativize */
191 relativize: function (element
, oldPos
) {
192 element
= MochiKit
.DOM
.getElement(element
);
193 if (element
.style
.position
== 'relative') {
196 MochiKit
.Position
.prepare();
198 var top
= parseFloat(element
.style
.top
|| 0) -
199 (oldPos
['top'] || 0);
200 var left
= parseFloat(element
.style
.left
|| 0) -
201 (oldPos
['left'] || 0);
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'];
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';
222 /** @id MochiKit.Position.page */
223 page: function (forElement
) {
227 var element
= forElement
;
229 valueT
+= element
.offsetTop
|| 0;
230 valueL
+= element
.offsetLeft
|| 0;
233 if (element
.offsetParent
== document
.body
&& MochiKit
.Style
.getStyle(element
, 'position') == 'absolute') {
236 } while (element
= element
.offsetParent
);
238 element
= forElement
;
240 valueT
-= element
.scrollTop
|| 0;
241 valueL
-= element
.scrollLeft
|| 0;
242 } while (element
= element
.parentNode
);
244 return new MochiKit
.Style
.Coordinates(valueL
, valueT
);
248 MochiKit
.Position
.__new__ = function (win
) {
249 var m
= MochiKit
.Base
;
251 ':common': this.EXPORT
,
252 ':all': m
.concat(this.EXPORT
, this.EXPORT_OK
)
255 m
.nameFunctions(this);
258 MochiKit
.Position
.__new__(this);