Style.js (13352B)
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);