93e77862afb37a0c9aa4cb70934ce2e1e417d87d
5 See <http://mochikit.com/> for documentation, downloads, license, etc.
7 (c) 2005-2006 Bob Ippolito, Beau Hartshorne. All rights Reserved.
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', []);
22 if (typeof(MochiKit
.Base
) == 'undefined') {
26 throw 'MochiKit.Style depends on MochiKit.Base!';
30 if (typeof(MochiKit
.DOM
) == 'undefined') {
34 throw 'MochiKit.Style depends on MochiKit.DOM!';
38 if (typeof(MochiKit
.Style
) == 'undefined') {
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
= [
57 'getElementDimensions',
58 'elementDimensions', // deprecated
59 'setElementDimensions',
61 'elementPosition', // deprecated
63 'setDisplayForElement',
66 'getViewportDimensions',
67 'getViewportPosition',
78 /** @id MochiKit.Style.Dimensions */
79 MochiKit
.Style
.Dimensions
= function (w
, 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__();
99 /** @id MochiKit.Style.Coordinates */
100 MochiKit
.Style
.Coordinates
= function (x
, 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
) {
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;
135 var value
= elem
.style
? elem
.style
[cssProperty
] : null;
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
];
146 if (cssProperty
== 'opacity') {
147 value
= parseFloat(value
);
150 if (/Opera/.test(navigator
.userAgent
) && (MochiKit
.Base
.find(['left', 'top', 'right', 'bottom'], cssProperty
) != -1)) {
151 if (MochiKit
.Style
.getStyle(elem
, 'position') == 'static') {
156 return value
== 'auto' ? null : value
;
159 /** @id MochiKit.Style.setStyle */
160 setStyle
: function (elem
, style
) {
161 elem
= MochiKit
.DOM
.getElement(elem
);
162 for (var name
in style
) {
163 if (name
== 'opacity') {
164 MochiKit
.Style
.setOpacity(elem
, style
[name
]);
166 elem
.style
[MochiKit
.Base
.camelize(name
)] = style
[name
];
171 /** @id MochiKit.Style.setOpacity */
172 setOpacity
: function (elem
, o
) {
173 elem
= MochiKit
.DOM
.getElement(elem
);
174 var self
= MochiKit
.Style
;
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, '');
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 + ')';
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
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
);
209 (!(elem
.x
&& elem
.y
) &&
210 (!elem
.parentNode
=== null ||
211 self
.getStyle(elem
, 'display') == 'none'))) {
215 var c
= new self
.Coordinates(0, 0);
219 var d
= MochiKit
.DOM
._document
;
220 var de
= d
.documentElement
;
223 if (!elem
.parentNode
&& elem
.x
&& elem
.y
) {
224 /* it's just a MochiKit.Style.Coordinates object */
227 } else if (elem
.getBoundingClientRect
) { // IE shortcut
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().
237 box
= elem
.getBoundingClientRect();
240 (de
.scrollLeft
|| b
.scrollLeft
) -
241 (de
.clientLeft
|| 0);
244 (de
.scrollTop
|| b
.scrollTop
) -
247 } else if (elem
.offsetParent
) {
248 c
.x
+= elem
.offsetLeft
;
249 c
.y
+= elem
.offsetTop
;
250 parent
= elem
.offsetParent
;
252 if (parent
!= elem
) {
254 c
.x
+= parent
.offsetLeft
;
255 c
.y
+= parent
.offsetTop
;
256 parent
= parent
.offsetParent
;
262 Opera < 9 and old Safari (absolute) incorrectly account for
263 body offsetTop and offsetLeft.
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')) {
278 if (typeof(relativeTo
) != 'undefined') {
279 relativeTo
= arguments
.callee(relativeTo
);
281 c
.x
-= (relativeTo
.x
|| 0);
282 c
.y
-= (relativeTo
.y
|| 0);
286 if (elem
.parentNode
) {
287 parent
= elem
.parentNode
;
293 var tagName
= parent
.tagName
.toUpperCase();
294 if (tagName
=== 'BODY' || tagName
=== 'HTML') {
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
;
303 if (parent
.parentNode
) {
304 parent
= parent
.parentNode
;
313 /** @id MochiKit.Style.setElementPosition */
314 setElementPosition
: function (elem
, newPos
/* optional */, units
) {
315 elem
= MochiKit
.DOM
.getElement(elem
);
316 if (typeof(units
) == 'undefined') {
320 var isUndefNull
= MochiKit
.Base
.isUndefinedOrNull
;
321 if (!isUndefNull(newPos
.x
)) {
322 newStyle
['left'] = newPos
.x
+ units
;
324 if (!isUndefNull(newPos
.y
)) {
325 newStyle
['top'] = newPos
.y
+ units
;
327 MochiKit
.DOM
.updateNodeAttributes(elem
, {'style': newStyle
});
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);
337 elem
= dom
.getElement(elem
);
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);
348 var originalVisibility
= s
.visibility
;
349 var originalPosition
= s
.position
;
350 s
.visibility
= 'hidden';
351 s
.position
= 'absolute';
353 var originalWidth
= elem
.offsetWidth
;
354 var originalHeight
= elem
.offsetHeight
;
356 s
.position
= originalPosition
;
357 s
.visibility
= originalVisibility
;
358 return new self
.Dimensions(originalWidth
, originalHeight
);
361 /** @id MochiKit.Style.setElementDimensions */
362 setElementDimensions
: function (elem
, newSize
/* optional */, units
) {
363 elem
= MochiKit
.DOM
.getElement(elem
);
364 if (typeof(units
) == 'undefined') {
368 var isUndefNull
= MochiKit
.Base
.isUndefinedOrNull
;
369 if (!isUndefNull(newSize
.w
)) {
370 newStyle
['width'] = newSize
.w
+ units
;
372 if (!isUndefNull(newSize
.h
)) {
373 newStyle
['height'] = newSize
.h
+ units
;
375 MochiKit
.DOM
.updateNodeAttributes(elem
, {'style': newStyle
});
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
]);
385 element
.style
.display
= display
;
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
;
400 } else if (b
.parentElement
.clientWidth
) {
401 d
.w
= b
.parentElement
.clientWidth
;
402 d
.h
= b
.parentElement
.clientHeight
;
403 } else if (b
&& b
.clientWidth
) {
405 d
.h
= b
.clientHeight
;
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
;
416 if (de
&& (de
.scrollTop
|| de
.scrollLeft
)) {
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');
436 ':common': this.EXPORT
,
437 ':all': m
.concat(this.EXPORT
, this.EXPORT_OK
)
440 m
.nameFunctions(this);
444 MochiKit
.Style
.__new__();
445 MochiKit
.Base
._exportSymbols(this, MochiKit
.Style
);