Make Build.PL less complainy and add manifest
[cxgn-jslib.git] / MochiKit / Position.js
blob23b0f181ceee8571a0fb2b9948ec7a7b96851b02
1 /***
3 MochiKit.Position 1.4
5 See <http://mochikit.com/> for documentation, downloads, license, etc.
7 (c) 2005-2006 Bob Ippolito and others.  All rights Reserved.
9 ***/
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', []);
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!';
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
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     },
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     },
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     },
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         }
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     },
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);
126     },
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     },
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();
152         var offsets = MochiKit.Position.positionedOffset(element);
153         var width = element.clientWidth;
154         var height = element.clientHeight;
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         };
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';
170         return oldStyle;
171     },
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     },
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();
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'];
208     },
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     },
222     /** @id MochiKit.Position.page */
223     page: function (forElement) {
224         var valueT = 0;
225         var valueL = 0;
227         var element = forElement;
228         do {
229             valueT += element.offsetTop  || 0;
230             valueL += element.offsetLeft || 0;
232             // Safari fix
233             if (element.offsetParent == document.body && MochiKit.Style.getStyle(element, 'position') == 'absolute') {
234                 break;
235             }
236         } while (element = element.offsetParent);
238         element = forElement;
239         do {
240             valueT -= element.scrollTop  || 0;
241             valueL -= element.scrollLeft || 0;
242         } while (element = element.parentNode);
244         return new MochiKit.Style.Coordinates(valueL, valueT);
245     }
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     };
255     m.nameFunctions(this);
258 MochiKit.Position.__new__(this);