upload fieldbook from manage phenotyping
[sgn.git] / js / MochiKit / Style.js
blob4dfe5fc2c491a438bf8aa16f876bc562c81955c8
1 /***
3 MochiKit.Style 1.4
5 See <http://mochikit.com/> for documentation, downloads, license, etc.
7 (c) 2005-2006 Bob Ippolito, Beau Hartshorne.  All rights Reserved.
9 ***/
11 if (typeof(dojo) != 'undefined') {
12     dojo.provide('MochiKit.Style');
13     dojo.require('MochiKit.Base');
14     dojo.require('MochiKit.DOM');
16 if (typeof(JSAN) != 'undefined') {
17     JSAN.use('MochiKit.Base', []);
18     JSAN.use('MochiKit.DOM', []);
21 try {
22     if (typeof(MochiKit.Base) == 'undefined') {
23         throw '';
24     }
25 } catch (e) {
26     throw 'MochiKit.Style depends on MochiKit.Base!';
29 try {
30     if (typeof(MochiKit.DOM) == 'undefined') {
31         throw '';
32     }
33 } catch (e) {
34     throw 'MochiKit.Style depends on MochiKit.DOM!';
38 if (typeof(MochiKit.Style) == 'undefined') {
39     MochiKit.Style = {};
42 MochiKit.Style.NAME = 'MochiKit.Style';
43 MochiKit.Style.VERSION = '1.4';
44 MochiKit.Style.__repr__ = function () {
45     return '[' + this.NAME + ' ' + this.VERSION + ']';
47 MochiKit.Style.toString = function () {
48     return this.__repr__();
51 MochiKit.Style.EXPORT_OK = [];
53 MochiKit.Style.EXPORT = [
54     'setStyle',
55     'setOpacity',
56     'getStyle',
57     'getElementDimensions',
58     'elementDimensions', // deprecated
59     'setElementDimensions',
60     'getElementPosition',
61     'elementPosition', // deprecated
62     'setElementPosition',
63     'setDisplayForElement',
64     'hideElement',
65     'showElement',
66     'getViewportDimensions',
67     'getViewportPosition',
68     'Dimensions',
69     'Coordinates'
75     Dimensions
78 /** @id MochiKit.Style.Dimensions */
79 MochiKit.Style.Dimensions = function (w, h) {
80     this.w = w;
81     this.h = h;
84 MochiKit.Style.Dimensions.prototype.__repr__ = function () {
85     var repr = MochiKit.Base.repr;
86     return '{w: '  + repr(this.w) + ', h: ' + repr(this.h) + '}';
89 MochiKit.Style.Dimensions.prototype.toString = function () {
90     return this.__repr__();
96     Coordinates
99 /** @id MochiKit.Style.Coordinates */
100 MochiKit.Style.Coordinates = function (x, y) {
101     this.x = x;
102     this.y = y;
105 MochiKit.Style.Coordinates.prototype.__repr__ = function () {
106     var repr = MochiKit.Base.repr;
107     return '{x: '  + repr(this.x) + ', y: ' + repr(this.y) + '}';
110 MochiKit.Style.Coordinates.prototype.toString = function () {
111     return this.__repr__();
115 MochiKit.Base.update(MochiKit.Style, {
117     /** @id MochiKit.Style.getStyle */
118     getStyle: function (elem, cssProperty) {
119         var dom = MochiKit.DOM;
120         var d = dom._document;
122         elem = dom.getElement(elem);
123         cssProperty = MochiKit.Base.camelize(cssProperty);
125         if (!elem || elem == d) {
126             return undefined;
127         }
128         if (cssProperty == 'opacity' && elem.filters) {
129             var opacity = (MochiKit.Style.getStyle(elem, 'filter') || '').match(/alpha\(opacity=(.*)\)/);
130             if (opacity && opacity[1]) {
131                 return parseFloat(opacity[1]) / 100;
132             }
133             return 1.0;
134         }
135         var value = elem.style ? elem.style[cssProperty] : null;
136         if (!value) {
137             if (d.defaultView && d.defaultView.getComputedStyle) {
138                 var css = d.defaultView.getComputedStyle(elem, null);
139                 cssProperty = cssProperty.replace(/([A-Z])/g, '-$1'
140                     ).toLowerCase(); // from dojo.style.toSelectorCase
141                 value = css ? css.getPropertyValue(cssProperty) : null;
142             } else if (elem.currentStyle) {
143                 value = elem.currentStyle[cssProperty];
144             }
145         }
146         if (cssProperty == 'opacity') {
147             value = parseFloat(value);
148         }
150         if (/Opera/.test(navigator.userAgent) && (MochiKit.Base.find(['left', 'top', 'right', 'bottom'], cssProperty) != -1)) {
151             if (MochiKit.Style.getStyle(elem, 'position') == 'static') {
152                 value = 'auto';
153             }
154         }
156         return value == 'auto' ? null : value;
157     },
159     /** @id MochiKit.Style.setStyle */
160     setStyle: function (elem, style) {
161         elem = MochiKit.DOM.getElement(elem);
162         for (name in style) {
163             if (name == 'opacity') {
164                 MochiKit.Style.setOpacity(elem, style[name]);
165             } else {
166                 elem.style[MochiKit.Base.camelize(name)] = style[name];
167             }
168         }
169     },
171     /** @id MochiKit.Style.setOpacity */
172     setOpacity: function (elem, o) {
173         elem = MochiKit.DOM.getElement(elem);
174         var self = MochiKit.Style;
175         if (o == 1) {
176             var toSet = /Gecko/.test(navigator.userAgent) && !(/Konqueror|AppleWebKit|KHTML/.test(navigator.userAgent));
177             elem.style["opacity"] = toSet ? 0.999999 : 1.0;
178             if (/MSIE/.test(navigator.userAgent)) {
179                 elem.style['filter'] =
180                     self.getStyle(elem, 'filter').replace(/alpha\([^\)]*\)/gi, '');
181             }
182         } else {
183             if (o < 0.00001) {
184                 o = 0;
185             }
186             elem.style["opacity"] = o;
187             if (/MSIE/.test(navigator.userAgent)) {
188                 elem.style['filter'] =
189                     self.getStyle(elem, 'filter').replace(/alpha\([^\)]*\)/gi, '') + 'alpha(opacity=' + o * 100 + ')';
190             }
191         }
192     },
194     /*
196         getElementPosition is adapted from YAHOO.util.Dom.getXY v0.9.0.
197         Copyright: Copyright (c) 2006, Yahoo! Inc. All rights reserved.
198         License: BSD, http://developer.yahoo.net/yui/license.txt
200     */
202     /** @id MochiKit.Style.getElementPosition */
203     getElementPosition: function (elem, /* optional */relativeTo) {
204         var self = MochiKit.Style;
205         var dom = MochiKit.DOM;
206         elem = dom.getElement(elem);
208         if (!elem ||
209             (!(elem.x && elem.y) &&
210             (!elem.parentNode === null ||
211             self.getStyle(elem, 'display') == 'none'))) {
212             return undefined;
213         }
215         var c = new self.Coordinates(0, 0);
216         var box = null;
217         var parent = null;
219         var d = MochiKit.DOM._document;
220         var de = d.documentElement;
221         var b = d.body;
223         if (!elem.parentNode && elem.x && elem.y) {
224             /* it's just a MochiKit.Style.Coordinates object */
225             c.x += elem.x || 0;
226             c.y += elem.y || 0;
227         } else if (elem.getBoundingClientRect) { // IE shortcut
228             /*
230                 The IE shortcut can be off by two. We fix it. See:
231                 http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp
233                 This is similar to the method used in
234                 MochiKit.Signal.Event.mouse().
236             */
237             box = elem.getBoundingClientRect();
239             c.x += box.left +
240                 (de.scrollLeft || b.scrollLeft) -
241                 (de.clientLeft || 0);
243             c.y += box.top +
244                 (de.scrollTop || b.scrollTop) -
245                 (de.clientTop || 0);
247         } else if (elem.offsetParent) {
248             c.x += elem.offsetLeft;
249             c.y += elem.offsetTop;
250             parent = elem.offsetParent;
252             if (parent != elem) {
253                 while (parent) {
254                     c.x += parent.offsetLeft;
255                     c.y += parent.offsetTop;
256                     parent = parent.offsetParent;
257                 }
258             }
260             /*
262                 Opera < 9 and old Safari (absolute) incorrectly account for
263                 body offsetTop and offsetLeft.
265             */
266             var ua = navigator.userAgent.toLowerCase();
267             if ((typeof(opera) != 'undefined' &&
268                 parseFloat(opera.version()) < 9) ||
269                 (ua.indexOf('AppleWebKit') != -1 &&
270                 self.getStyle(elem, 'position') == 'absolute')) {
272                 c.x -= b.offsetLeft;
273                 c.y -= b.offsetTop;
275             }
276         }
278         if (typeof(relativeTo) != 'undefined') {
279             relativeTo = arguments.callee(relativeTo);
280             if (relativeTo) {
281                 c.x -= (relativeTo.x || 0);
282                 c.y -= (relativeTo.y || 0);
283             }
284         }
286         if (elem.parentNode) {
287             parent = elem.parentNode;
288         } else {
289             parent = null;
290         }
292         while (parent) {
293             var tagName = parent.tagName.toUpperCase();
294             if (tagName === 'BODY' || tagName === 'HTML') {
295                 break;
296             }
297             var disp = self.getStyle(parent, 'display');
298             // Handle strange Opera bug for some display
299             if (disp != 'inline' && disp != 'table-row') {
300                 c.x -= parent.scrollLeft;
301                 c.y -= parent.scrollTop;
302             }
303             if (parent.parentNode) {
304                 parent = parent.parentNode;
305             } else {
306                 parent = null;
307             }
308         }
310         return c;
311     },
313     /** @id MochiKit.Style.setElementPosition */
314     setElementPosition: function (elem, newPos/* optional */, units) {
315         elem = MochiKit.DOM.getElement(elem);
316         if (typeof(units) == 'undefined') {
317             units = 'px';
318         }
319         var newStyle = {};
320         var isUndefNull = MochiKit.Base.isUndefinedOrNull;
321         if (!isUndefNull(newPos.x)) {
322             newStyle['left'] = newPos.x + units;
323         }
324         if (!isUndefNull(newPos.y)) {
325             newStyle['top'] = newPos.y + units;
326         }
327         MochiKit.DOM.updateNodeAttributes(elem, {'style': newStyle});
328     },
330     /** @id MochiKit.Style.getElementDimensions */
331     getElementDimensions: function (elem) {
332         var self = MochiKit.Style;
333         var dom = MochiKit.DOM;
334         if (typeof(elem.w) == 'number' || typeof(elem.h) == 'number') {
335             return new self.Dimensions(elem.w || 0, elem.h || 0);
336         }
337         elem = dom.getElement(elem);
338         if (!elem) {
339             return undefined;
340         }
341         var disp = self.getStyle(elem, 'display');
342         // display can be empty/undefined on WebKit/KHTML
343         if (disp != 'none' && disp !== '' && typeof(disp) != 'undefined') {
344             return new self.Dimensions(elem.offsetWidth || 0,
345                 elem.offsetHeight || 0);
346         }
347         var s = elem.style;
348         var originalVisibility = s.visibility;
349         var originalPosition = s.position;
350         s.visibility = 'hidden';
351         s.position = 'absolute';
352         s.display = '';
353         var originalWidth = elem.offsetWidth;
354         var originalHeight = elem.offsetHeight;
355         s.display = 'none';
356         s.position = originalPosition;
357         s.visibility = originalVisibility;
358         return new self.Dimensions(originalWidth, originalHeight);
359     },
361     /** @id MochiKit.Style.setElementDimensions */
362     setElementDimensions: function (elem, newSize/* optional */, units) {
363         elem = MochiKit.DOM.getElement(elem);
364         if (typeof(units) == 'undefined') {
365             units = 'px';
366         }
367         var newStyle = {};
368         var isUndefNull = MochiKit.Base.isUndefinedOrNull;
369         if (!isUndefNull(newSize.w)) {
370             newStyle['width'] = newSize.w + units;
371         }
372         if (!isUndefNull(newSize.h)) {
373             newStyle['height'] = newSize.h + units;
374         }
375         MochiKit.DOM.updateNodeAttributes(elem, {'style': newStyle});
376     },
378     /** @id MochiKit.Style.setDisplayForElement */
379     setDisplayForElement: function (display, element/*, ...*/) {
380         var elements = MochiKit.Base.extend(null, arguments, 1);
381         var getElement = MochiKit.DOM.getElement;
382         for (var i = 0; i < elements.length; i++) {
383             element = getElement(elements[i]);
384             if (element) {
385                 element.style.display = display;
386             }
387         }
388     },
390     /** @id MochiKit.Style.getViewportDimensions */
391     getViewportDimensions: function () {
392         var d = new MochiKit.Style.Dimensions();
394         var w = MochiKit.DOM._window;
395         var b = MochiKit.DOM._document.body;
397         if (w.innerWidth) {
398             d.w = w.innerWidth;
399             d.h = w.innerHeight;
400         } else if (b.parentElement.clientWidth) {
401             d.w = b.parentElement.clientWidth;
402             d.h = b.parentElement.clientHeight;
403         } else if (b && b.clientWidth) {
404             d.w = b.clientWidth;
405             d.h = b.clientHeight;
406         }
407         return d;
408     },
410     /** @id MochiKit.Style.getViewportPosition */
411     getViewportPosition: function () {
412         var c = new MochiKit.Style.Coordinates(0, 0);
413         var d = MochiKit.DOM._document;
414         var de = d.documentElement;
415         var db = d.body;
416         if (de && (de.scrollTop || de.scrollLeft)) {
417             c.x = de.scrollLeft;
418             c.y = de.scrollTop;
419         } else if (db) {
420             c.x = db.scrollLeft;
421             c.y = db.scrollTop;
422         }
423         return c;
424     },
426     __new__: function () {
427         var m = MochiKit.Base;
429         this.elementPosition = this.getElementPosition;
430         this.elementDimensions = this.getElementDimensions;
432         this.hideElement = m.partial(this.setDisplayForElement, 'none');
433         this.showElement = m.partial(this.setDisplayForElement, 'block');
435         this.EXPORT_TAGS = {
436             ':common': this.EXPORT,
437             ':all': m.concat(this.EXPORT, this.EXPORT_OK)
438         };
440         m.nameFunctions(this);
441     }
444 MochiKit.Style.__new__();
445 MochiKit.Base._exportSymbols(this, MochiKit.Style);