Commit | Line | Data |
---|---|---|
6a1aa64f DV |
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 | JSAN.use('MochiKit.DOM', []); | |
19 | } | |
20 | ||
21 | try { | |
22 | if (typeof(MochiKit.Base) == 'undefined') { | |
23 | throw ''; | |
24 | } | |
25 | } catch (e) { | |
26 | throw 'MochiKit.Style depends on MochiKit.Base!'; | |
27 | } | |
28 | ||
29 | try { | |
30 | if (typeof(MochiKit.DOM) == 'undefined') { | |
31 | throw ''; | |
32 | } | |
33 | } catch (e) { | |
34 | throw 'MochiKit.Style depends on MochiKit.DOM!'; | |
35 | } | |
36 | ||
37 | ||
38 | if (typeof(MochiKit.Style) == 'undefined') { | |
39 | MochiKit.Style = {}; | |
40 | } | |
41 | ||
42 | MochiKit.Style.NAME = 'MochiKit.Style'; | |
43 | MochiKit.Style.VERSION = '1.4'; | |
44 | MochiKit.Style.__repr__ = function () { | |
45 | return '[' + this.NAME + ' ' + this.VERSION + ']'; | |
46 | }; | |
47 | MochiKit.Style.toString = function () { | |
48 | return this.__repr__(); | |
49 | }; | |
50 | ||
51 | MochiKit.Style.EXPORT_OK = []; | |
52 | ||
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' | |
70 | ]; | |
71 | ||
72 | ||
73 | /* | |
74 | ||
75 | Dimensions | |
76 | ||
77 | */ | |
78 | /** @id MochiKit.Style.Dimensions */ | |
79 | MochiKit.Style.Dimensions = function (w, h) { | |
80 | this.w = w; | |
81 | this.h = h; | |
82 | }; | |
83 | ||
84 | MochiKit.Style.Dimensions.prototype.__repr__ = function () { | |
85 | var repr = MochiKit.Base.repr; | |
86 | return '{w: ' + repr(this.w) + ', h: ' + repr(this.h) + '}'; | |
87 | }; | |
88 | ||
89 | MochiKit.Style.Dimensions.prototype.toString = function () { | |
90 | return this.__repr__(); | |
91 | }; | |
92 | ||
93 | ||
94 | /* | |
95 | ||
96 | Coordinates | |
97 | ||
98 | */ | |
99 | /** @id MochiKit.Style.Coordinates */ | |
100 | MochiKit.Style.Coordinates = function (x, y) { | |
101 | this.x = x; | |
102 | this.y = y; | |
103 | }; | |
104 | ||
105 | MochiKit.Style.Coordinates.prototype.__repr__ = function () { | |
106 | var repr = MochiKit.Base.repr; | |
107 | return '{x: ' + repr(this.x) + ', y: ' + repr(this.y) + '}'; | |
108 | }; | |
109 | ||
110 | MochiKit.Style.Coordinates.prototype.toString = function () { | |
111 | return this.__repr__(); | |
112 | }; | |
113 | ||
114 | ||
115 | MochiKit.Base.update(MochiKit.Style, { | |
116 | ||
117 | /** @id MochiKit.Style.getStyle */ | |
118 | getStyle: function (elem, cssProperty) { | |
119 | var dom = MochiKit.DOM; | |
120 | var d = dom._document; | |
121 | ||
122 | elem = dom.getElement(elem); | |
123 | cssProperty = MochiKit.Base.camelize(cssProperty); | |
124 | ||
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 | } | |
149 | ||
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 | } | |
155 | ||
156 | return value == 'auto' ? null : value; | |
157 | }, | |
158 | ||
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]); | |
165 | } else { | |
166 | elem.style[MochiKit.Base.camelize(name)] = style[name]; | |
167 | } | |
168 | } | |
169 | }, | |
170 | ||
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 | }, | |
193 | ||
194 | /* | |
195 | ||
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 | |
199 | ||
200 | */ | |
201 | ||
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); | |
207 | ||
208 | if (!elem || | |
209 | (!(elem.x && elem.y) && | |
210 | (!elem.parentNode === null || | |
211 | self.getStyle(elem, 'display') == 'none'))) { | |
212 | return undefined; | |
213 | } | |
214 | ||
215 | var c = new self.Coordinates(0, 0); | |
216 | var box = null; | |
217 | var parent = null; | |
218 | ||
219 | var d = MochiKit.DOM._document; | |
220 | var de = d.documentElement; | |
221 | var b = d.body; | |
222 | ||
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 | /* | |
229 | ||
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 | |
232 | ||
233 | This is similar to the method used in | |
234 | MochiKit.Signal.Event.mouse(). | |
235 | ||
236 | */ | |
237 | box = elem.getBoundingClientRect(); | |
238 | ||
239 | c.x += box.left + | |
240 | (de.scrollLeft || b.scrollLeft) - | |
241 | (de.clientLeft || 0); | |
242 | ||
243 | c.y += box.top + | |
244 | (de.scrollTop || b.scrollTop) - | |
245 | (de.clientTop || 0); | |
246 | ||
247 | } else if (elem.offsetParent) { | |
248 | c.x += elem.offsetLeft; | |
249 | c.y += elem.offsetTop; | |
250 | parent = elem.offsetParent; | |
251 | ||
252 | if (parent != elem) { | |
253 | while (parent) { | |
254 | c.x += parent.offsetLeft; | |
255 | c.y += parent.offsetTop; | |
256 | parent = parent.offsetParent; | |
257 | } | |
258 | } | |
259 | ||
260 | /* | |
261 | ||
262 | Opera < 9 and old Safari (absolute) incorrectly account for | |
263 | body offsetTop and offsetLeft. | |
264 | ||
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')) { | |
271 | ||
272 | c.x -= b.offsetLeft; | |
273 | c.y -= b.offsetTop; | |
274 | ||
275 | } | |
276 | } | |
277 | ||
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 | } | |
285 | ||
286 | if (elem.parentNode) { | |
287 | parent = elem.parentNode; | |
288 | } else { | |
289 | parent = null; | |
290 | } | |
291 | ||
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 | } | |
309 | ||
310 | return c; | |
311 | }, | |
312 | ||
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 | }, | |
329 | ||
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 | }, | |
360 | ||
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 | }, | |
377 | ||
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 | }, | |
389 | ||
390 | /** @id MochiKit.Style.getViewportDimensions */ | |
391 | getViewportDimensions: function () { | |
392 | var d = new MochiKit.Style.Dimensions(); | |
393 | ||
394 | var w = MochiKit.DOM._window; | |
395 | var b = MochiKit.DOM._document.body; | |
396 | ||
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 | }, | |
409 | ||
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 | }, | |
425 | ||
426 | __new__: function () { | |
427 | var m = MochiKit.Base; | |
428 | ||
429 | this.elementPosition = this.getElementPosition; | |
430 | this.elementDimensions = this.getElementDimensions; | |
431 | ||
432 | this.hideElement = m.partial(this.setDisplayForElement, 'none'); | |
433 | this.showElement = m.partial(this.setDisplayForElement, 'block'); | |
434 | ||
435 | this.EXPORT_TAGS = { | |
436 | ':common': this.EXPORT, | |
437 | ':all': m.concat(this.EXPORT, this.EXPORT_OK) | |
438 | }; | |
439 | ||
440 | m.nameFunctions(this); | |
441 | } | |
442 | }); | |
443 | ||
444 | MochiKit.Style.__new__(); | |
445 | MochiKit.Base._exportSymbols(this, MochiKit.Style); |