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