1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/testing/mochitest/tests/MochiKit-1.4.2/MochiKit/Visual.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,2026 @@ 1.4 +/*** 1.5 + 1.6 +MochiKit.Visual 1.4.2 1.7 + 1.8 +See <http://mochikit.com/> for documentation, downloads, license, etc. 1.9 + 1.10 +(c) 2005 Bob Ippolito and others. All rights Reserved. 1.11 + 1.12 +***/ 1.13 + 1.14 +MochiKit.Base._deps('Visual', ['Base', 'DOM', 'Style', 'Color', 'Position']); 1.15 + 1.16 +MochiKit.Visual.NAME = "MochiKit.Visual"; 1.17 +MochiKit.Visual.VERSION = "1.4.2"; 1.18 + 1.19 +MochiKit.Visual.__repr__ = function () { 1.20 + return "[" + this.NAME + " " + this.VERSION + "]"; 1.21 +}; 1.22 + 1.23 +MochiKit.Visual.toString = function () { 1.24 + return this.__repr__(); 1.25 +}; 1.26 + 1.27 +MochiKit.Visual._RoundCorners = function (e, options) { 1.28 + e = MochiKit.DOM.getElement(e); 1.29 + this._setOptions(options); 1.30 + if (this.options.__unstable__wrapElement) { 1.31 + e = this._doWrap(e); 1.32 + } 1.33 + 1.34 + var color = this.options.color; 1.35 + var C = MochiKit.Color.Color; 1.36 + if (this.options.color === "fromElement") { 1.37 + color = C.fromBackground(e); 1.38 + } else if (!(color instanceof C)) { 1.39 + color = C.fromString(color); 1.40 + } 1.41 + this.isTransparent = (color.asRGB().a <= 0); 1.42 + 1.43 + var bgColor = this.options.bgColor; 1.44 + if (this.options.bgColor === "fromParent") { 1.45 + bgColor = C.fromBackground(e.offsetParent); 1.46 + } else if (!(bgColor instanceof C)) { 1.47 + bgColor = C.fromString(bgColor); 1.48 + } 1.49 + 1.50 + this._roundCornersImpl(e, color, bgColor); 1.51 +}; 1.52 + 1.53 +MochiKit.Visual._RoundCorners.prototype = { 1.54 + _doWrap: function (e) { 1.55 + var parent = e.parentNode; 1.56 + var doc = MochiKit.DOM.currentDocument(); 1.57 + if (typeof(doc.defaultView) === "undefined" 1.58 + || doc.defaultView === null) { 1.59 + return e; 1.60 + } 1.61 + var style = doc.defaultView.getComputedStyle(e, null); 1.62 + if (typeof(style) === "undefined" || style === null) { 1.63 + return e; 1.64 + } 1.65 + var wrapper = MochiKit.DOM.DIV({"style": { 1.66 + display: "block", 1.67 + // convert padding to margin 1.68 + marginTop: style.getPropertyValue("padding-top"), 1.69 + marginRight: style.getPropertyValue("padding-right"), 1.70 + marginBottom: style.getPropertyValue("padding-bottom"), 1.71 + marginLeft: style.getPropertyValue("padding-left"), 1.72 + // remove padding so the rounding looks right 1.73 + padding: "0px" 1.74 + /* 1.75 + paddingRight: "0px", 1.76 + paddingLeft: "0px" 1.77 + */ 1.78 + }}); 1.79 + wrapper.innerHTML = e.innerHTML; 1.80 + e.innerHTML = ""; 1.81 + e.appendChild(wrapper); 1.82 + return e; 1.83 + }, 1.84 + 1.85 + _roundCornersImpl: function (e, color, bgColor) { 1.86 + if (this.options.border) { 1.87 + this._renderBorder(e, bgColor); 1.88 + } 1.89 + if (this._isTopRounded()) { 1.90 + this._roundTopCorners(e, color, bgColor); 1.91 + } 1.92 + if (this._isBottomRounded()) { 1.93 + this._roundBottomCorners(e, color, bgColor); 1.94 + } 1.95 + }, 1.96 + 1.97 + _renderBorder: function (el, bgColor) { 1.98 + var borderValue = "1px solid " + this._borderColor(bgColor); 1.99 + var borderL = "border-left: " + borderValue; 1.100 + var borderR = "border-right: " + borderValue; 1.101 + var style = "style='" + borderL + ";" + borderR + "'"; 1.102 + el.innerHTML = "<div " + style + ">" + el.innerHTML + "</div>"; 1.103 + }, 1.104 + 1.105 + _roundTopCorners: function (el, color, bgColor) { 1.106 + var corner = this._createCorner(bgColor); 1.107 + for (var i = 0; i < this.options.numSlices; i++) { 1.108 + corner.appendChild( 1.109 + this._createCornerSlice(color, bgColor, i, "top") 1.110 + ); 1.111 + } 1.112 + el.style.paddingTop = 0; 1.113 + el.insertBefore(corner, el.firstChild); 1.114 + }, 1.115 + 1.116 + _roundBottomCorners: function (el, color, bgColor) { 1.117 + var corner = this._createCorner(bgColor); 1.118 + for (var i = (this.options.numSlices - 1); i >= 0; i--) { 1.119 + corner.appendChild( 1.120 + this._createCornerSlice(color, bgColor, i, "bottom") 1.121 + ); 1.122 + } 1.123 + el.style.paddingBottom = 0; 1.124 + el.appendChild(corner); 1.125 + }, 1.126 + 1.127 + _createCorner: function (bgColor) { 1.128 + var dom = MochiKit.DOM; 1.129 + return dom.DIV({style: {backgroundColor: bgColor.toString()}}); 1.130 + }, 1.131 + 1.132 + _createCornerSlice: function (color, bgColor, n, position) { 1.133 + var slice = MochiKit.DOM.SPAN(); 1.134 + 1.135 + var inStyle = slice.style; 1.136 + inStyle.backgroundColor = color.toString(); 1.137 + inStyle.display = "block"; 1.138 + inStyle.height = "1px"; 1.139 + inStyle.overflow = "hidden"; 1.140 + inStyle.fontSize = "1px"; 1.141 + 1.142 + var borderColor = this._borderColor(color, bgColor); 1.143 + if (this.options.border && n === 0) { 1.144 + inStyle.borderTopStyle = "solid"; 1.145 + inStyle.borderTopWidth = "1px"; 1.146 + inStyle.borderLeftWidth = "0px"; 1.147 + inStyle.borderRightWidth = "0px"; 1.148 + inStyle.borderBottomWidth = "0px"; 1.149 + // assumes css compliant box model 1.150 + inStyle.height = "0px"; 1.151 + inStyle.borderColor = borderColor.toString(); 1.152 + } else if (borderColor) { 1.153 + inStyle.borderColor = borderColor.toString(); 1.154 + inStyle.borderStyle = "solid"; 1.155 + inStyle.borderWidth = "0px 1px"; 1.156 + } 1.157 + 1.158 + if (!this.options.compact && (n == (this.options.numSlices - 1))) { 1.159 + inStyle.height = "2px"; 1.160 + } 1.161 + 1.162 + this._setMargin(slice, n, position); 1.163 + this._setBorder(slice, n, position); 1.164 + 1.165 + return slice; 1.166 + }, 1.167 + 1.168 + _setOptions: function (options) { 1.169 + this.options = { 1.170 + corners: "all", 1.171 + color: "fromElement", 1.172 + bgColor: "fromParent", 1.173 + blend: true, 1.174 + border: false, 1.175 + compact: false, 1.176 + __unstable__wrapElement: false 1.177 + }; 1.178 + MochiKit.Base.update(this.options, options); 1.179 + 1.180 + this.options.numSlices = (this.options.compact ? 2 : 4); 1.181 + }, 1.182 + 1.183 + _whichSideTop: function () { 1.184 + var corners = this.options.corners; 1.185 + if (this._hasString(corners, "all", "top")) { 1.186 + return ""; 1.187 + } 1.188 + 1.189 + var has_tl = (corners.indexOf("tl") != -1); 1.190 + var has_tr = (corners.indexOf("tr") != -1); 1.191 + if (has_tl && has_tr) { 1.192 + return ""; 1.193 + } 1.194 + if (has_tl) { 1.195 + return "left"; 1.196 + } 1.197 + if (has_tr) { 1.198 + return "right"; 1.199 + } 1.200 + return ""; 1.201 + }, 1.202 + 1.203 + _whichSideBottom: function () { 1.204 + var corners = this.options.corners; 1.205 + if (this._hasString(corners, "all", "bottom")) { 1.206 + return ""; 1.207 + } 1.208 + 1.209 + var has_bl = (corners.indexOf('bl') != -1); 1.210 + var has_br = (corners.indexOf('br') != -1); 1.211 + if (has_bl && has_br) { 1.212 + return ""; 1.213 + } 1.214 + if (has_bl) { 1.215 + return "left"; 1.216 + } 1.217 + if (has_br) { 1.218 + return "right"; 1.219 + } 1.220 + return ""; 1.221 + }, 1.222 + 1.223 + _borderColor: function (color, bgColor) { 1.224 + if (color == "transparent") { 1.225 + return bgColor; 1.226 + } else if (this.options.border) { 1.227 + return this.options.border; 1.228 + } else if (this.options.blend) { 1.229 + return bgColor.blendedColor(color); 1.230 + } 1.231 + return ""; 1.232 + }, 1.233 + 1.234 + 1.235 + _setMargin: function (el, n, corners) { 1.236 + var marginSize = this._marginSize(n) + "px"; 1.237 + var whichSide = ( 1.238 + corners == "top" ? this._whichSideTop() : this._whichSideBottom() 1.239 + ); 1.240 + var style = el.style; 1.241 + 1.242 + if (whichSide == "left") { 1.243 + style.marginLeft = marginSize; 1.244 + style.marginRight = "0px"; 1.245 + } else if (whichSide == "right") { 1.246 + style.marginRight = marginSize; 1.247 + style.marginLeft = "0px"; 1.248 + } else { 1.249 + style.marginLeft = marginSize; 1.250 + style.marginRight = marginSize; 1.251 + } 1.252 + }, 1.253 + 1.254 + _setBorder: function (el, n, corners) { 1.255 + var borderSize = this._borderSize(n) + "px"; 1.256 + var whichSide = ( 1.257 + corners == "top" ? this._whichSideTop() : this._whichSideBottom() 1.258 + ); 1.259 + 1.260 + var style = el.style; 1.261 + if (whichSide == "left") { 1.262 + style.borderLeftWidth = borderSize; 1.263 + style.borderRightWidth = "0px"; 1.264 + } else if (whichSide == "right") { 1.265 + style.borderRightWidth = borderSize; 1.266 + style.borderLeftWidth = "0px"; 1.267 + } else { 1.268 + style.borderLeftWidth = borderSize; 1.269 + style.borderRightWidth = borderSize; 1.270 + } 1.271 + }, 1.272 + 1.273 + _marginSize: function (n) { 1.274 + if (this.isTransparent) { 1.275 + return 0; 1.276 + } 1.277 + 1.278 + var o = this.options; 1.279 + if (o.compact && o.blend) { 1.280 + var smBlendedMarginSizes = [1, 0]; 1.281 + return smBlendedMarginSizes[n]; 1.282 + } else if (o.compact) { 1.283 + var compactMarginSizes = [2, 1]; 1.284 + return compactMarginSizes[n]; 1.285 + } else if (o.blend) { 1.286 + var blendedMarginSizes = [3, 2, 1, 0]; 1.287 + return blendedMarginSizes[n]; 1.288 + } else { 1.289 + var marginSizes = [5, 3, 2, 1]; 1.290 + return marginSizes[n]; 1.291 + } 1.292 + }, 1.293 + 1.294 + _borderSize: function (n) { 1.295 + var o = this.options; 1.296 + var borderSizes; 1.297 + if (o.compact && (o.blend || this.isTransparent)) { 1.298 + return 1; 1.299 + } else if (o.compact) { 1.300 + borderSizes = [1, 0]; 1.301 + } else if (o.blend) { 1.302 + borderSizes = [2, 1, 1, 1]; 1.303 + } else if (o.border) { 1.304 + borderSizes = [0, 2, 0, 0]; 1.305 + } else if (this.isTransparent) { 1.306 + borderSizes = [5, 3, 2, 1]; 1.307 + } else { 1.308 + return 0; 1.309 + } 1.310 + return borderSizes[n]; 1.311 + }, 1.312 + 1.313 + _hasString: function (str) { 1.314 + for (var i = 1; i< arguments.length; i++) { 1.315 + if (str.indexOf(arguments[i]) != -1) { 1.316 + return true; 1.317 + } 1.318 + } 1.319 + return false; 1.320 + }, 1.321 + 1.322 + _isTopRounded: function () { 1.323 + return this._hasString(this.options.corners, 1.324 + "all", "top", "tl", "tr" 1.325 + ); 1.326 + }, 1.327 + 1.328 + _isBottomRounded: function () { 1.329 + return this._hasString(this.options.corners, 1.330 + "all", "bottom", "bl", "br" 1.331 + ); 1.332 + }, 1.333 + 1.334 + _hasSingleTextChild: function (el) { 1.335 + return (el.childNodes.length == 1 && el.childNodes[0].nodeType == 3); 1.336 + } 1.337 +}; 1.338 + 1.339 +/** @id MochiKit.Visual.roundElement */ 1.340 +MochiKit.Visual.roundElement = function (e, options) { 1.341 + new MochiKit.Visual._RoundCorners(e, options); 1.342 +}; 1.343 + 1.344 +/** @id MochiKit.Visual.roundClass */ 1.345 +MochiKit.Visual.roundClass = function (tagName, className, options) { 1.346 + var elements = MochiKit.DOM.getElementsByTagAndClassName( 1.347 + tagName, className 1.348 + ); 1.349 + for (var i = 0; i < elements.length; i++) { 1.350 + MochiKit.Visual.roundElement(elements[i], options); 1.351 + } 1.352 +}; 1.353 + 1.354 +/** @id MochiKit.Visual.tagifyText */ 1.355 +MochiKit.Visual.tagifyText = function (element, /* optional */tagifyStyle) { 1.356 + /*** 1.357 + 1.358 + Change a node text to character in tags. 1.359 + 1.360 + @param tagifyStyle: the style to apply to character nodes, default to 1.361 + 'position: relative'. 1.362 + 1.363 + ***/ 1.364 + tagifyStyle = tagifyStyle || 'position:relative'; 1.365 + if (/MSIE/.test(navigator.userAgent)) { 1.366 + tagifyStyle += ';zoom:1'; 1.367 + } 1.368 + element = MochiKit.DOM.getElement(element); 1.369 + var ma = MochiKit.Base.map; 1.370 + ma(function (child) { 1.371 + if (child.nodeType == 3) { 1.372 + ma(function (character) { 1.373 + element.insertBefore( 1.374 + MochiKit.DOM.SPAN({style: tagifyStyle}, 1.375 + character == ' ' ? String.fromCharCode(160) : character), child); 1.376 + }, child.nodeValue.split('')); 1.377 + MochiKit.DOM.removeElement(child); 1.378 + } 1.379 + }, element.childNodes); 1.380 +}; 1.381 + 1.382 +/** @id MochiKit.Visual.forceRerendering */ 1.383 +MochiKit.Visual.forceRerendering = function (element) { 1.384 + try { 1.385 + element = MochiKit.DOM.getElement(element); 1.386 + var n = document.createTextNode(' '); 1.387 + element.appendChild(n); 1.388 + element.removeChild(n); 1.389 + } catch(e) { 1.390 + } 1.391 +}; 1.392 + 1.393 +/** @id MochiKit.Visual.multiple */ 1.394 +MochiKit.Visual.multiple = function (elements, effect, /* optional */options) { 1.395 + /*** 1.396 + 1.397 + Launch the same effect subsequently on given elements. 1.398 + 1.399 + ***/ 1.400 + options = MochiKit.Base.update({ 1.401 + speed: 0.1, delay: 0.0 1.402 + }, options); 1.403 + var masterDelay = options.delay; 1.404 + var index = 0; 1.405 + MochiKit.Base.map(function (innerelement) { 1.406 + options.delay = index * options.speed + masterDelay; 1.407 + new effect(innerelement, options); 1.408 + index += 1; 1.409 + }, elements); 1.410 +}; 1.411 + 1.412 +MochiKit.Visual.PAIRS = { 1.413 + 'slide': ['slideDown', 'slideUp'], 1.414 + 'blind': ['blindDown', 'blindUp'], 1.415 + 'appear': ['appear', 'fade'], 1.416 + 'size': ['grow', 'shrink'] 1.417 +}; 1.418 + 1.419 +/** @id MochiKit.Visual.toggle */ 1.420 +MochiKit.Visual.toggle = function (element, /* optional */effect, /* optional */options) { 1.421 + /*** 1.422 + 1.423 + Toggle an item between two state depending of its visibility, making 1.424 + a effect between these states. Default effect is 'appear', can be 1.425 + 'slide' or 'blind'. 1.426 + 1.427 + ***/ 1.428 + element = MochiKit.DOM.getElement(element); 1.429 + effect = (effect || 'appear').toLowerCase(); 1.430 + options = MochiKit.Base.update({ 1.431 + queue: {position: 'end', scope: (element.id || 'global'), limit: 1} 1.432 + }, options); 1.433 + var v = MochiKit.Visual; 1.434 + v[MochiKit.Style.getStyle(element, 'display') != 'none' ? 1.435 + v.PAIRS[effect][1] : v.PAIRS[effect][0]](element, options); 1.436 +}; 1.437 + 1.438 +/*** 1.439 + 1.440 +Transitions: define functions calculating variations depending of a position. 1.441 + 1.442 +***/ 1.443 + 1.444 +MochiKit.Visual.Transitions = {}; 1.445 + 1.446 +/** @id MochiKit.Visual.Transitions.linear */ 1.447 +MochiKit.Visual.Transitions.linear = function (pos) { 1.448 + return pos; 1.449 +}; 1.450 + 1.451 +/** @id MochiKit.Visual.Transitions.sinoidal */ 1.452 +MochiKit.Visual.Transitions.sinoidal = function (pos) { 1.453 + return 0.5 - Math.cos(pos*Math.PI)/2; 1.454 +}; 1.455 + 1.456 +/** @id MochiKit.Visual.Transitions.reverse */ 1.457 +MochiKit.Visual.Transitions.reverse = function (pos) { 1.458 + return 1 - pos; 1.459 +}; 1.460 + 1.461 +/** @id MochiKit.Visual.Transitions.flicker */ 1.462 +MochiKit.Visual.Transitions.flicker = function (pos) { 1.463 + return 0.25 - Math.cos(pos*Math.PI)/4 + Math.random()/2; 1.464 +}; 1.465 + 1.466 +/** @id MochiKit.Visual.Transitions.wobble */ 1.467 +MochiKit.Visual.Transitions.wobble = function (pos) { 1.468 + return 0.5 - Math.cos(9*pos*Math.PI)/2; 1.469 +}; 1.470 + 1.471 +/** @id MochiKit.Visual.Transitions.pulse */ 1.472 +MochiKit.Visual.Transitions.pulse = function (pos, pulses) { 1.473 + if (pulses) { 1.474 + pos *= 2 * pulses; 1.475 + } else { 1.476 + pos *= 10; 1.477 + } 1.478 + var decimals = pos - Math.floor(pos); 1.479 + return (Math.floor(pos) % 2 == 0) ? decimals : 1 - decimals; 1.480 +}; 1.481 + 1.482 +/** @id MochiKit.Visual.Transitions.parabolic */ 1.483 +MochiKit.Visual.Transitions.parabolic = function (pos) { 1.484 + return pos * pos; 1.485 +}; 1.486 + 1.487 +/** @id MochiKit.Visual.Transitions.none */ 1.488 +MochiKit.Visual.Transitions.none = function (pos) { 1.489 + return 0; 1.490 +}; 1.491 + 1.492 +/** @id MochiKit.Visual.Transitions.full */ 1.493 +MochiKit.Visual.Transitions.full = function (pos) { 1.494 + return 1; 1.495 +}; 1.496 + 1.497 +/*** 1.498 + 1.499 +Core effects 1.500 + 1.501 +***/ 1.502 + 1.503 +MochiKit.Visual.ScopedQueue = function () { 1.504 + var cls = arguments.callee; 1.505 + if (!(this instanceof cls)) { 1.506 + return new cls(); 1.507 + } 1.508 + this.__init__(); 1.509 +}; 1.510 + 1.511 +MochiKit.Base.update(MochiKit.Visual.ScopedQueue.prototype, { 1.512 + __init__: function () { 1.513 + this.effects = []; 1.514 + this.interval = null; 1.515 + }, 1.516 + 1.517 + /** @id MochiKit.Visual.ScopedQueue.prototype.add */ 1.518 + add: function (effect) { 1.519 + var timestamp = new Date().getTime(); 1.520 + 1.521 + var position = (typeof(effect.options.queue) == 'string') ? 1.522 + effect.options.queue : effect.options.queue.position; 1.523 + 1.524 + var ma = MochiKit.Base.map; 1.525 + switch (position) { 1.526 + case 'front': 1.527 + // move unstarted effects after this effect 1.528 + ma(function (e) { 1.529 + if (e.state == 'idle') { 1.530 + e.startOn += effect.finishOn; 1.531 + e.finishOn += effect.finishOn; 1.532 + } 1.533 + }, this.effects); 1.534 + break; 1.535 + case 'end': 1.536 + var finish; 1.537 + // start effect after last queued effect has finished 1.538 + ma(function (e) { 1.539 + var i = e.finishOn; 1.540 + if (i >= (finish || i)) { 1.541 + finish = i; 1.542 + } 1.543 + }, this.effects); 1.544 + timestamp = finish || timestamp; 1.545 + break; 1.546 + case 'break': 1.547 + ma(function (e) { 1.548 + e.finalize(); 1.549 + }, this.effects); 1.550 + break; 1.551 + } 1.552 + 1.553 + effect.startOn += timestamp; 1.554 + effect.finishOn += timestamp; 1.555 + if (!effect.options.queue.limit || 1.556 + this.effects.length < effect.options.queue.limit) { 1.557 + this.effects.push(effect); 1.558 + } 1.559 + 1.560 + if (!this.interval) { 1.561 + this.interval = this.startLoop(MochiKit.Base.bind(this.loop, this), 1.562 + 40); 1.563 + } 1.564 + }, 1.565 + 1.566 + /** @id MochiKit.Visual.ScopedQueue.prototype.startLoop */ 1.567 + startLoop: function (func, interval) { 1.568 + return setInterval(func, interval); 1.569 + }, 1.570 + 1.571 + /** @id MochiKit.Visual.ScopedQueue.prototype.remove */ 1.572 + remove: function (effect) { 1.573 + this.effects = MochiKit.Base.filter(function (e) { 1.574 + return e != effect; 1.575 + }, this.effects); 1.576 + if (!this.effects.length) { 1.577 + this.stopLoop(this.interval); 1.578 + this.interval = null; 1.579 + } 1.580 + }, 1.581 + 1.582 + /** @id MochiKit.Visual.ScopedQueue.prototype.stopLoop */ 1.583 + stopLoop: function (interval) { 1.584 + clearInterval(interval); 1.585 + }, 1.586 + 1.587 + /** @id MochiKit.Visual.ScopedQueue.prototype.loop */ 1.588 + loop: function () { 1.589 + var timePos = new Date().getTime(); 1.590 + MochiKit.Base.map(function (effect) { 1.591 + effect.loop(timePos); 1.592 + }, this.effects); 1.593 + } 1.594 +}); 1.595 + 1.596 +MochiKit.Visual.Queues = { 1.597 + instances: {}, 1.598 + 1.599 + get: function (queueName) { 1.600 + if (typeof(queueName) != 'string') { 1.601 + return queueName; 1.602 + } 1.603 + 1.604 + if (!this.instances[queueName]) { 1.605 + this.instances[queueName] = new MochiKit.Visual.ScopedQueue(); 1.606 + } 1.607 + return this.instances[queueName]; 1.608 + } 1.609 +}; 1.610 + 1.611 +MochiKit.Visual.Queue = MochiKit.Visual.Queues.get('global'); 1.612 + 1.613 +MochiKit.Visual.DefaultOptions = { 1.614 + transition: MochiKit.Visual.Transitions.sinoidal, 1.615 + duration: 1.0, // seconds 1.616 + fps: 25.0, // max. 25fps due to MochiKit.Visual.Queue implementation 1.617 + sync: false, // true for combining 1.618 + from: 0.0, 1.619 + to: 1.0, 1.620 + delay: 0.0, 1.621 + queue: 'parallel' 1.622 +}; 1.623 + 1.624 +MochiKit.Visual.Base = function () {}; 1.625 + 1.626 +MochiKit.Visual.Base.prototype = { 1.627 + /*** 1.628 + 1.629 + Basic class for all Effects. Define a looping mechanism called for each step 1.630 + of an effect. Don't instantiate it, only subclass it. 1.631 + 1.632 + ***/ 1.633 + 1.634 + __class__ : MochiKit.Visual.Base, 1.635 + 1.636 + /** @id MochiKit.Visual.Base.prototype.start */ 1.637 + start: function (options) { 1.638 + var v = MochiKit.Visual; 1.639 + this.options = MochiKit.Base.setdefault(options, 1.640 + v.DefaultOptions); 1.641 + this.currentFrame = 0; 1.642 + this.state = 'idle'; 1.643 + this.startOn = this.options.delay*1000; 1.644 + this.finishOn = this.startOn + (this.options.duration*1000); 1.645 + this.event('beforeStart'); 1.646 + if (!this.options.sync) { 1.647 + v.Queues.get(typeof(this.options.queue) == 'string' ? 1.648 + 'global' : this.options.queue.scope).add(this); 1.649 + } 1.650 + }, 1.651 + 1.652 + /** @id MochiKit.Visual.Base.prototype.loop */ 1.653 + loop: function (timePos) { 1.654 + if (timePos >= this.startOn) { 1.655 + if (timePos >= this.finishOn) { 1.656 + return this.finalize(); 1.657 + } 1.658 + var pos = (timePos - this.startOn) / (this.finishOn - this.startOn); 1.659 + var frame = 1.660 + Math.round(pos * this.options.fps * this.options.duration); 1.661 + if (frame > this.currentFrame) { 1.662 + this.render(pos); 1.663 + this.currentFrame = frame; 1.664 + } 1.665 + } 1.666 + }, 1.667 + 1.668 + /** @id MochiKit.Visual.Base.prototype.render */ 1.669 + render: function (pos) { 1.670 + if (this.state == 'idle') { 1.671 + this.state = 'running'; 1.672 + this.event('beforeSetup'); 1.673 + this.setup(); 1.674 + this.event('afterSetup'); 1.675 + } 1.676 + if (this.state == 'running') { 1.677 + if (this.options.transition) { 1.678 + pos = this.options.transition(pos); 1.679 + } 1.680 + pos *= (this.options.to - this.options.from); 1.681 + pos += this.options.from; 1.682 + this.event('beforeUpdate'); 1.683 + this.update(pos); 1.684 + this.event('afterUpdate'); 1.685 + } 1.686 + }, 1.687 + 1.688 + /** @id MochiKit.Visual.Base.prototype.cancel */ 1.689 + cancel: function () { 1.690 + if (!this.options.sync) { 1.691 + MochiKit.Visual.Queues.get(typeof(this.options.queue) == 'string' ? 1.692 + 'global' : this.options.queue.scope).remove(this); 1.693 + } 1.694 + this.state = 'finished'; 1.695 + }, 1.696 + 1.697 + /** @id MochiKit.Visual.Base.prototype.finalize */ 1.698 + finalize: function () { 1.699 + this.render(1.0); 1.700 + this.cancel(); 1.701 + this.event('beforeFinish'); 1.702 + this.finish(); 1.703 + this.event('afterFinish'); 1.704 + }, 1.705 + 1.706 + setup: function () { 1.707 + }, 1.708 + 1.709 + finish: function () { 1.710 + }, 1.711 + 1.712 + update: function (position) { 1.713 + }, 1.714 + 1.715 + /** @id MochiKit.Visual.Base.prototype.event */ 1.716 + event: function (eventName) { 1.717 + if (this.options[eventName + 'Internal']) { 1.718 + this.options[eventName + 'Internal'](this); 1.719 + } 1.720 + if (this.options[eventName]) { 1.721 + this.options[eventName](this); 1.722 + } 1.723 + }, 1.724 + 1.725 + /** @id MochiKit.Visual.Base.prototype.repr */ 1.726 + repr: function () { 1.727 + return '[' + this.__class__.NAME + ', options:' + 1.728 + MochiKit.Base.repr(this.options) + ']'; 1.729 + } 1.730 +}; 1.731 + 1.732 +/** @id MochiKit.Visual.Parallel */ 1.733 +MochiKit.Visual.Parallel = function (effects, options) { 1.734 + var cls = arguments.callee; 1.735 + if (!(this instanceof cls)) { 1.736 + return new cls(effects, options); 1.737 + } 1.738 + 1.739 + this.__init__(effects, options); 1.740 +}; 1.741 + 1.742 +MochiKit.Visual.Parallel.prototype = new MochiKit.Visual.Base(); 1.743 + 1.744 +MochiKit.Base.update(MochiKit.Visual.Parallel.prototype, { 1.745 + /*** 1.746 + 1.747 + Run multiple effects at the same time. 1.748 + 1.749 + ***/ 1.750 + 1.751 + __class__ : MochiKit.Visual.Parallel, 1.752 + 1.753 + __init__: function (effects, options) { 1.754 + this.effects = effects || []; 1.755 + this.start(options); 1.756 + }, 1.757 + 1.758 + /** @id MochiKit.Visual.Parallel.prototype.update */ 1.759 + update: function (position) { 1.760 + MochiKit.Base.map(function (effect) { 1.761 + effect.render(position); 1.762 + }, this.effects); 1.763 + }, 1.764 + 1.765 + /** @id MochiKit.Visual.Parallel.prototype.finish */ 1.766 + finish: function () { 1.767 + MochiKit.Base.map(function (effect) { 1.768 + effect.finalize(); 1.769 + }, this.effects); 1.770 + } 1.771 +}); 1.772 + 1.773 +/** @id MochiKit.Visual.Sequence */ 1.774 +MochiKit.Visual.Sequence = function (effects, options) { 1.775 + var cls = arguments.callee; 1.776 + if (!(this instanceof cls)) { 1.777 + return new cls(effects, options); 1.778 + } 1.779 + this.__init__(effects, options); 1.780 +}; 1.781 + 1.782 +MochiKit.Visual.Sequence.prototype = new MochiKit.Visual.Base(); 1.783 + 1.784 +MochiKit.Base.update(MochiKit.Visual.Sequence.prototype, { 1.785 + 1.786 + __class__ : MochiKit.Visual.Sequence, 1.787 + 1.788 + __init__: function (effects, options) { 1.789 + var defs = { transition: MochiKit.Visual.Transitions.linear, 1.790 + duration: 0 }; 1.791 + this.effects = effects || []; 1.792 + MochiKit.Base.map(function (effect) { 1.793 + defs.duration += effect.options.duration; 1.794 + }, this.effects); 1.795 + MochiKit.Base.setdefault(options, defs); 1.796 + this.start(options); 1.797 + }, 1.798 + 1.799 + /** @id MochiKit.Visual.Sequence.prototype.update */ 1.800 + update: function (position) { 1.801 + var time = position * this.options.duration; 1.802 + for (var i = 0; i < this.effects.length; i++) { 1.803 + var effect = this.effects[i]; 1.804 + if (time <= effect.options.duration) { 1.805 + effect.render(time / effect.options.duration); 1.806 + break; 1.807 + } else { 1.808 + time -= effect.options.duration; 1.809 + } 1.810 + } 1.811 + }, 1.812 + 1.813 + /** @id MochiKit.Visual.Sequence.prototype.finish */ 1.814 + finish: function () { 1.815 + MochiKit.Base.map(function (effect) { 1.816 + effect.finalize(); 1.817 + }, this.effects); 1.818 + } 1.819 +}); 1.820 + 1.821 +/** @id MochiKit.Visual.Opacity */ 1.822 +MochiKit.Visual.Opacity = function (element, options) { 1.823 + var cls = arguments.callee; 1.824 + if (!(this instanceof cls)) { 1.825 + return new cls(element, options); 1.826 + } 1.827 + this.__init__(element, options); 1.828 +}; 1.829 + 1.830 +MochiKit.Visual.Opacity.prototype = new MochiKit.Visual.Base(); 1.831 + 1.832 +MochiKit.Base.update(MochiKit.Visual.Opacity.prototype, { 1.833 + /*** 1.834 + 1.835 + Change the opacity of an element. 1.836 + 1.837 + @param options: 'from' and 'to' change the starting and ending opacities. 1.838 + Must be between 0.0 and 1.0. Default to current opacity and 1.0. 1.839 + 1.840 + ***/ 1.841 + 1.842 + __class__ : MochiKit.Visual.Opacity, 1.843 + 1.844 + __init__: function (element, /* optional */options) { 1.845 + var b = MochiKit.Base; 1.846 + var s = MochiKit.Style; 1.847 + this.element = MochiKit.DOM.getElement(element); 1.848 + // make this work on IE on elements without 'layout' 1.849 + if (this.element.currentStyle && 1.850 + (!this.element.currentStyle.hasLayout)) { 1.851 + s.setStyle(this.element, {zoom: 1}); 1.852 + } 1.853 + options = b.update({ 1.854 + from: s.getStyle(this.element, 'opacity') || 0.0, 1.855 + to: 1.0 1.856 + }, options); 1.857 + this.start(options); 1.858 + }, 1.859 + 1.860 + /** @id MochiKit.Visual.Opacity.prototype.update */ 1.861 + update: function (position) { 1.862 + MochiKit.Style.setStyle(this.element, {'opacity': position}); 1.863 + } 1.864 +}); 1.865 + 1.866 +/** @id MochiKit.Visual.Move.prototype */ 1.867 +MochiKit.Visual.Move = function (element, options) { 1.868 + var cls = arguments.callee; 1.869 + if (!(this instanceof cls)) { 1.870 + return new cls(element, options); 1.871 + } 1.872 + this.__init__(element, options); 1.873 +}; 1.874 + 1.875 +MochiKit.Visual.Move.prototype = new MochiKit.Visual.Base(); 1.876 + 1.877 +MochiKit.Base.update(MochiKit.Visual.Move.prototype, { 1.878 + /*** 1.879 + 1.880 + Move an element between its current position to a defined position 1.881 + 1.882 + @param options: 'x' and 'y' for final positions, default to 0, 0. 1.883 + 1.884 + ***/ 1.885 + 1.886 + __class__ : MochiKit.Visual.Move, 1.887 + 1.888 + __init__: function (element, /* optional */options) { 1.889 + this.element = MochiKit.DOM.getElement(element); 1.890 + options = MochiKit.Base.update({ 1.891 + x: 0, 1.892 + y: 0, 1.893 + mode: 'relative' 1.894 + }, options); 1.895 + this.start(options); 1.896 + }, 1.897 + 1.898 + /** @id MochiKit.Visual.Move.prototype.setup */ 1.899 + setup: function () { 1.900 + // Bug in Opera: Opera returns the 'real' position of a static element 1.901 + // or relative element that does not have top/left explicitly set. 1.902 + // ==> Always set top and left for position relative elements in your 1.903 + // stylesheets (to 0 if you do not need them) 1.904 + MochiKit.Style.makePositioned(this.element); 1.905 + 1.906 + var s = this.element.style; 1.907 + var originalVisibility = s.visibility; 1.908 + var originalDisplay = s.display; 1.909 + if (originalDisplay == 'none') { 1.910 + s.visibility = 'hidden'; 1.911 + s.display = ''; 1.912 + } 1.913 + 1.914 + this.originalLeft = parseFloat(MochiKit.Style.getStyle(this.element, 'left') || '0'); 1.915 + this.originalTop = parseFloat(MochiKit.Style.getStyle(this.element, 'top') || '0'); 1.916 + 1.917 + if (this.options.mode == 'absolute') { 1.918 + // absolute movement, so we need to calc deltaX and deltaY 1.919 + this.options.x -= this.originalLeft; 1.920 + this.options.y -= this.originalTop; 1.921 + } 1.922 + if (originalDisplay == 'none') { 1.923 + s.visibility = originalVisibility; 1.924 + s.display = originalDisplay; 1.925 + } 1.926 + }, 1.927 + 1.928 + /** @id MochiKit.Visual.Move.prototype.update */ 1.929 + update: function (position) { 1.930 + MochiKit.Style.setStyle(this.element, { 1.931 + left: Math.round(this.options.x * position + this.originalLeft) + 'px', 1.932 + top: Math.round(this.options.y * position + this.originalTop) + 'px' 1.933 + }); 1.934 + } 1.935 +}); 1.936 + 1.937 +/** @id MochiKit.Visual.Scale */ 1.938 +MochiKit.Visual.Scale = function (element, percent, options) { 1.939 + var cls = arguments.callee; 1.940 + if (!(this instanceof cls)) { 1.941 + return new cls(element, percent, options); 1.942 + } 1.943 + this.__init__(element, percent, options); 1.944 +}; 1.945 + 1.946 +MochiKit.Visual.Scale.prototype = new MochiKit.Visual.Base(); 1.947 + 1.948 +MochiKit.Base.update(MochiKit.Visual.Scale.prototype, { 1.949 + /*** 1.950 + 1.951 + Change the size of an element. 1.952 + 1.953 + @param percent: final_size = percent*original_size 1.954 + 1.955 + @param options: several options changing scale behaviour 1.956 + 1.957 + ***/ 1.958 + 1.959 + __class__ : MochiKit.Visual.Scale, 1.960 + 1.961 + __init__: function (element, percent, /* optional */options) { 1.962 + this.element = MochiKit.DOM.getElement(element); 1.963 + options = MochiKit.Base.update({ 1.964 + scaleX: true, 1.965 + scaleY: true, 1.966 + scaleContent: true, 1.967 + scaleFromCenter: false, 1.968 + scaleMode: 'box', // 'box' or 'contents' or {} with provided values 1.969 + scaleFrom: 100.0, 1.970 + scaleTo: percent 1.971 + }, options); 1.972 + this.start(options); 1.973 + }, 1.974 + 1.975 + /** @id MochiKit.Visual.Scale.prototype.setup */ 1.976 + setup: function () { 1.977 + this.restoreAfterFinish = this.options.restoreAfterFinish || false; 1.978 + this.elementPositioning = MochiKit.Style.getStyle(this.element, 1.979 + 'position'); 1.980 + 1.981 + var ma = MochiKit.Base.map; 1.982 + var b = MochiKit.Base.bind; 1.983 + this.originalStyle = {}; 1.984 + ma(b(function (k) { 1.985 + this.originalStyle[k] = this.element.style[k]; 1.986 + }, this), ['top', 'left', 'width', 'height', 'fontSize']); 1.987 + 1.988 + this.originalTop = this.element.offsetTop; 1.989 + this.originalLeft = this.element.offsetLeft; 1.990 + 1.991 + var fontSize = MochiKit.Style.getStyle(this.element, 1.992 + 'font-size') || '100%'; 1.993 + ma(b(function (fontSizeType) { 1.994 + if (fontSize.indexOf(fontSizeType) > 0) { 1.995 + this.fontSize = parseFloat(fontSize); 1.996 + this.fontSizeType = fontSizeType; 1.997 + } 1.998 + }, this), ['em', 'px', '%']); 1.999 + 1.1000 + this.factor = (this.options.scaleTo - this.options.scaleFrom)/100; 1.1001 + 1.1002 + if (/^content/.test(this.options.scaleMode)) { 1.1003 + this.dims = [this.element.scrollHeight, this.element.scrollWidth]; 1.1004 + } else if (this.options.scaleMode == 'box') { 1.1005 + this.dims = [this.element.offsetHeight, this.element.offsetWidth]; 1.1006 + } else { 1.1007 + this.dims = [this.options.scaleMode.originalHeight, 1.1008 + this.options.scaleMode.originalWidth]; 1.1009 + } 1.1010 + }, 1.1011 + 1.1012 + /** @id MochiKit.Visual.Scale.prototype.update */ 1.1013 + update: function (position) { 1.1014 + var currentScale = (this.options.scaleFrom/100.0) + 1.1015 + (this.factor * position); 1.1016 + if (this.options.scaleContent && this.fontSize) { 1.1017 + MochiKit.Style.setStyle(this.element, { 1.1018 + fontSize: this.fontSize * currentScale + this.fontSizeType 1.1019 + }); 1.1020 + } 1.1021 + this.setDimensions(this.dims[0] * currentScale, 1.1022 + this.dims[1] * currentScale); 1.1023 + }, 1.1024 + 1.1025 + /** @id MochiKit.Visual.Scale.prototype.finish */ 1.1026 + finish: function () { 1.1027 + if (this.restoreAfterFinish) { 1.1028 + MochiKit.Style.setStyle(this.element, this.originalStyle); 1.1029 + } 1.1030 + }, 1.1031 + 1.1032 + /** @id MochiKit.Visual.Scale.prototype.setDimensions */ 1.1033 + setDimensions: function (height, width) { 1.1034 + var d = {}; 1.1035 + var r = Math.round; 1.1036 + if (/MSIE/.test(navigator.userAgent)) { 1.1037 + r = Math.ceil; 1.1038 + } 1.1039 + if (this.options.scaleX) { 1.1040 + d.width = r(width) + 'px'; 1.1041 + } 1.1042 + if (this.options.scaleY) { 1.1043 + d.height = r(height) + 'px'; 1.1044 + } 1.1045 + if (this.options.scaleFromCenter) { 1.1046 + var topd = (height - this.dims[0])/2; 1.1047 + var leftd = (width - this.dims[1])/2; 1.1048 + if (this.elementPositioning == 'absolute') { 1.1049 + if (this.options.scaleY) { 1.1050 + d.top = this.originalTop - topd + 'px'; 1.1051 + } 1.1052 + if (this.options.scaleX) { 1.1053 + d.left = this.originalLeft - leftd + 'px'; 1.1054 + } 1.1055 + } else { 1.1056 + if (this.options.scaleY) { 1.1057 + d.top = -topd + 'px'; 1.1058 + } 1.1059 + if (this.options.scaleX) { 1.1060 + d.left = -leftd + 'px'; 1.1061 + } 1.1062 + } 1.1063 + } 1.1064 + MochiKit.Style.setStyle(this.element, d); 1.1065 + } 1.1066 +}); 1.1067 + 1.1068 +/** @id MochiKit.Visual.Highlight */ 1.1069 +MochiKit.Visual.Highlight = function (element, options) { 1.1070 + var cls = arguments.callee; 1.1071 + if (!(this instanceof cls)) { 1.1072 + return new cls(element, options); 1.1073 + } 1.1074 + this.__init__(element, options); 1.1075 +}; 1.1076 + 1.1077 +MochiKit.Visual.Highlight.prototype = new MochiKit.Visual.Base(); 1.1078 + 1.1079 +MochiKit.Base.update(MochiKit.Visual.Highlight.prototype, { 1.1080 + /*** 1.1081 + 1.1082 + Highlight an item of the page. 1.1083 + 1.1084 + @param options: 'startcolor' for choosing highlighting color, default 1.1085 + to '#ffff99'. 1.1086 + 1.1087 + ***/ 1.1088 + 1.1089 + __class__ : MochiKit.Visual.Highlight, 1.1090 + 1.1091 + __init__: function (element, /* optional */options) { 1.1092 + this.element = MochiKit.DOM.getElement(element); 1.1093 + options = MochiKit.Base.update({ 1.1094 + startcolor: '#ffff99' 1.1095 + }, options); 1.1096 + this.start(options); 1.1097 + }, 1.1098 + 1.1099 + /** @id MochiKit.Visual.Highlight.prototype.setup */ 1.1100 + setup: function () { 1.1101 + var b = MochiKit.Base; 1.1102 + var s = MochiKit.Style; 1.1103 + // Prevent executing on elements not in the layout flow 1.1104 + if (s.getStyle(this.element, 'display') == 'none') { 1.1105 + this.cancel(); 1.1106 + return; 1.1107 + } 1.1108 + // Disable background image during the effect 1.1109 + this.oldStyle = { 1.1110 + backgroundImage: s.getStyle(this.element, 'background-image') 1.1111 + }; 1.1112 + s.setStyle(this.element, { 1.1113 + backgroundImage: 'none' 1.1114 + }); 1.1115 + 1.1116 + if (!this.options.endcolor) { 1.1117 + this.options.endcolor = 1.1118 + MochiKit.Color.Color.fromBackground(this.element).toHexString(); 1.1119 + } 1.1120 + if (b.isUndefinedOrNull(this.options.restorecolor)) { 1.1121 + this.options.restorecolor = s.getStyle(this.element, 1.1122 + 'background-color'); 1.1123 + } 1.1124 + // init color calculations 1.1125 + this._base = b.map(b.bind(function (i) { 1.1126 + return parseInt( 1.1127 + this.options.startcolor.slice(i*2 + 1, i*2 + 3), 16); 1.1128 + }, this), [0, 1, 2]); 1.1129 + this._delta = b.map(b.bind(function (i) { 1.1130 + return parseInt(this.options.endcolor.slice(i*2 + 1, i*2 + 3), 16) 1.1131 + - this._base[i]; 1.1132 + }, this), [0, 1, 2]); 1.1133 + }, 1.1134 + 1.1135 + /** @id MochiKit.Visual.Highlight.prototype.update */ 1.1136 + update: function (position) { 1.1137 + var m = '#'; 1.1138 + MochiKit.Base.map(MochiKit.Base.bind(function (i) { 1.1139 + m += MochiKit.Color.toColorPart(Math.round(this._base[i] + 1.1140 + this._delta[i]*position)); 1.1141 + }, this), [0, 1, 2]); 1.1142 + MochiKit.Style.setStyle(this.element, { 1.1143 + backgroundColor: m 1.1144 + }); 1.1145 + }, 1.1146 + 1.1147 + /** @id MochiKit.Visual.Highlight.prototype.finish */ 1.1148 + finish: function () { 1.1149 + MochiKit.Style.setStyle(this.element, 1.1150 + MochiKit.Base.update(this.oldStyle, { 1.1151 + backgroundColor: this.options.restorecolor 1.1152 + })); 1.1153 + } 1.1154 +}); 1.1155 + 1.1156 +/** @id MochiKit.Visual.ScrollTo */ 1.1157 +MochiKit.Visual.ScrollTo = function (element, options) { 1.1158 + var cls = arguments.callee; 1.1159 + if (!(this instanceof cls)) { 1.1160 + return new cls(element, options); 1.1161 + } 1.1162 + this.__init__(element, options); 1.1163 +}; 1.1164 + 1.1165 +MochiKit.Visual.ScrollTo.prototype = new MochiKit.Visual.Base(); 1.1166 + 1.1167 +MochiKit.Base.update(MochiKit.Visual.ScrollTo.prototype, { 1.1168 + /*** 1.1169 + 1.1170 + Scroll to an element in the page. 1.1171 + 1.1172 + ***/ 1.1173 + 1.1174 + __class__ : MochiKit.Visual.ScrollTo, 1.1175 + 1.1176 + __init__: function (element, /* optional */options) { 1.1177 + this.element = MochiKit.DOM.getElement(element); 1.1178 + this.start(options); 1.1179 + }, 1.1180 + 1.1181 + /** @id MochiKit.Visual.ScrollTo.prototype.setup */ 1.1182 + setup: function () { 1.1183 + var p = MochiKit.Position; 1.1184 + p.prepare(); 1.1185 + var offsets = p.cumulativeOffset(this.element); 1.1186 + if (this.options.offset) { 1.1187 + offsets.y += this.options.offset; 1.1188 + } 1.1189 + var max; 1.1190 + if (window.innerHeight) { 1.1191 + max = window.innerHeight - window.height; 1.1192 + } else if (document.documentElement && 1.1193 + document.documentElement.clientHeight) { 1.1194 + max = document.documentElement.clientHeight - 1.1195 + document.body.scrollHeight; 1.1196 + } else if (document.body) { 1.1197 + max = document.body.clientHeight - document.body.scrollHeight; 1.1198 + } 1.1199 + this.scrollStart = p.windowOffset.y; 1.1200 + this.delta = (offsets.y > max ? max : offsets.y) - this.scrollStart; 1.1201 + }, 1.1202 + 1.1203 + /** @id MochiKit.Visual.ScrollTo.prototype.update */ 1.1204 + update: function (position) { 1.1205 + var p = MochiKit.Position; 1.1206 + p.prepare(); 1.1207 + window.scrollTo(p.windowOffset.x, this.scrollStart + (position * this.delta)); 1.1208 + } 1.1209 +}); 1.1210 + 1.1211 +MochiKit.Visual.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/; 1.1212 + 1.1213 +MochiKit.Visual.Morph = function (element, options) { 1.1214 + var cls = arguments.callee; 1.1215 + if (!(this instanceof cls)) { 1.1216 + return new cls(element, options); 1.1217 + } 1.1218 + this.__init__(element, options); 1.1219 +}; 1.1220 + 1.1221 +MochiKit.Visual.Morph.prototype = new MochiKit.Visual.Base(); 1.1222 + 1.1223 +MochiKit.Base.update(MochiKit.Visual.Morph.prototype, { 1.1224 + /*** 1.1225 + 1.1226 + Morph effect: make a transformation from current style to the given style, 1.1227 + automatically making a transition between the two. 1.1228 + 1.1229 + ***/ 1.1230 + 1.1231 + __class__ : MochiKit.Visual.Morph, 1.1232 + 1.1233 + __init__: function (element, /* optional */options) { 1.1234 + this.element = MochiKit.DOM.getElement(element); 1.1235 + this.start(options); 1.1236 + }, 1.1237 + 1.1238 + /** @id MochiKit.Visual.Morph.prototype.setup */ 1.1239 + setup: function () { 1.1240 + var b = MochiKit.Base; 1.1241 + var style = this.options.style; 1.1242 + this.styleStart = {}; 1.1243 + this.styleEnd = {}; 1.1244 + this.units = {}; 1.1245 + var value, unit; 1.1246 + for (var s in style) { 1.1247 + value = style[s]; 1.1248 + s = b.camelize(s); 1.1249 + if (MochiKit.Visual.CSS_LENGTH.test(value)) { 1.1250 + var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/); 1.1251 + value = parseFloat(components[1]); 1.1252 + unit = (components.length == 3) ? components[2] : null; 1.1253 + this.styleEnd[s] = value; 1.1254 + this.units[s] = unit; 1.1255 + value = MochiKit.Style.getStyle(this.element, s); 1.1256 + components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/); 1.1257 + value = parseFloat(components[1]); 1.1258 + this.styleStart[s] = value; 1.1259 + } else if (/[Cc]olor$/.test(s)) { 1.1260 + var c = MochiKit.Color.Color; 1.1261 + value = c.fromString(value); 1.1262 + if (value) { 1.1263 + this.units[s] = "color"; 1.1264 + this.styleEnd[s] = value.toHexString(); 1.1265 + value = MochiKit.Style.getStyle(this.element, s); 1.1266 + this.styleStart[s] = c.fromString(value).toHexString(); 1.1267 + 1.1268 + this.styleStart[s] = b.map(b.bind(function (i) { 1.1269 + return parseInt( 1.1270 + this.styleStart[s].slice(i*2 + 1, i*2 + 3), 16); 1.1271 + }, this), [0, 1, 2]); 1.1272 + this.styleEnd[s] = b.map(b.bind(function (i) { 1.1273 + return parseInt( 1.1274 + this.styleEnd[s].slice(i*2 + 1, i*2 + 3), 16); 1.1275 + }, this), [0, 1, 2]); 1.1276 + } 1.1277 + } else { 1.1278 + // For non-length & non-color properties, we just set the value 1.1279 + this.element.style[s] = value; 1.1280 + } 1.1281 + } 1.1282 + }, 1.1283 + 1.1284 + /** @id MochiKit.Visual.Morph.prototype.update */ 1.1285 + update: function (position) { 1.1286 + var value; 1.1287 + for (var s in this.styleStart) { 1.1288 + if (this.units[s] == "color") { 1.1289 + var m = '#'; 1.1290 + var start = this.styleStart[s]; 1.1291 + var end = this.styleEnd[s]; 1.1292 + MochiKit.Base.map(MochiKit.Base.bind(function (i) { 1.1293 + m += MochiKit.Color.toColorPart(Math.round(start[i] + 1.1294 + (end[i] - start[i])*position)); 1.1295 + }, this), [0, 1, 2]); 1.1296 + this.element.style[s] = m; 1.1297 + } else { 1.1298 + value = this.styleStart[s] + Math.round((this.styleEnd[s] - this.styleStart[s]) * position * 1000) / 1000 + this.units[s]; 1.1299 + this.element.style[s] = value; 1.1300 + } 1.1301 + } 1.1302 + } 1.1303 +}); 1.1304 + 1.1305 +/*** 1.1306 + 1.1307 +Combination effects. 1.1308 + 1.1309 +***/ 1.1310 + 1.1311 +/** @id MochiKit.Visual.fade */ 1.1312 +MochiKit.Visual.fade = function (element, /* optional */ options) { 1.1313 + /*** 1.1314 + 1.1315 + Fade a given element: change its opacity and hide it in the end. 1.1316 + 1.1317 + @param options: 'to' and 'from' to change opacity. 1.1318 + 1.1319 + ***/ 1.1320 + var s = MochiKit.Style; 1.1321 + var oldOpacity = s.getStyle(element, 'opacity'); 1.1322 + options = MochiKit.Base.update({ 1.1323 + from: s.getStyle(element, 'opacity') || 1.0, 1.1324 + to: 0.0, 1.1325 + afterFinishInternal: function (effect) { 1.1326 + if (effect.options.to !== 0) { 1.1327 + return; 1.1328 + } 1.1329 + s.hideElement(effect.element); 1.1330 + s.setStyle(effect.element, {'opacity': oldOpacity}); 1.1331 + } 1.1332 + }, options); 1.1333 + return new MochiKit.Visual.Opacity(element, options); 1.1334 +}; 1.1335 + 1.1336 +/** @id MochiKit.Visual.appear */ 1.1337 +MochiKit.Visual.appear = function (element, /* optional */ options) { 1.1338 + /*** 1.1339 + 1.1340 + Make an element appear. 1.1341 + 1.1342 + @param options: 'to' and 'from' to change opacity. 1.1343 + 1.1344 + ***/ 1.1345 + var s = MochiKit.Style; 1.1346 + var v = MochiKit.Visual; 1.1347 + options = MochiKit.Base.update({ 1.1348 + from: (s.getStyle(element, 'display') == 'none' ? 0.0 : 1.1349 + s.getStyle(element, 'opacity') || 0.0), 1.1350 + to: 1.0, 1.1351 + // force Safari to render floated elements properly 1.1352 + afterFinishInternal: function (effect) { 1.1353 + v.forceRerendering(effect.element); 1.1354 + }, 1.1355 + beforeSetupInternal: function (effect) { 1.1356 + s.setStyle(effect.element, {'opacity': effect.options.from}); 1.1357 + s.showElement(effect.element); 1.1358 + } 1.1359 + }, options); 1.1360 + return new v.Opacity(element, options); 1.1361 +}; 1.1362 + 1.1363 +/** @id MochiKit.Visual.puff */ 1.1364 +MochiKit.Visual.puff = function (element, /* optional */ options) { 1.1365 + /*** 1.1366 + 1.1367 + 'Puff' an element: grow it to double size, fading it and make it hidden. 1.1368 + 1.1369 + ***/ 1.1370 + var s = MochiKit.Style; 1.1371 + var v = MochiKit.Visual; 1.1372 + element = MochiKit.DOM.getElement(element); 1.1373 + var elementDimensions = MochiKit.Style.getElementDimensions(element, true); 1.1374 + var oldStyle = { 1.1375 + position: s.getStyle(element, 'position'), 1.1376 + top: element.style.top, 1.1377 + left: element.style.left, 1.1378 + width: element.style.width, 1.1379 + height: element.style.height, 1.1380 + opacity: s.getStyle(element, 'opacity') 1.1381 + }; 1.1382 + options = MochiKit.Base.update({ 1.1383 + beforeSetupInternal: function (effect) { 1.1384 + MochiKit.Position.absolutize(effect.effects[0].element); 1.1385 + }, 1.1386 + afterFinishInternal: function (effect) { 1.1387 + s.hideElement(effect.effects[0].element); 1.1388 + s.setStyle(effect.effects[0].element, oldStyle); 1.1389 + }, 1.1390 + scaleContent: true, 1.1391 + scaleFromCenter: true 1.1392 + }, options); 1.1393 + return new v.Parallel( 1.1394 + [new v.Scale(element, 200, 1.1395 + {sync: true, scaleFromCenter: options.scaleFromCenter, 1.1396 + scaleMode: {originalHeight: elementDimensions.h, 1.1397 + originalWidth: elementDimensions.w}, 1.1398 + scaleContent: options.scaleContent, restoreAfterFinish: true}), 1.1399 + new v.Opacity(element, {sync: true, to: 0.0 })], 1.1400 + options); 1.1401 +}; 1.1402 + 1.1403 +/** @id MochiKit.Visual.blindUp */ 1.1404 +MochiKit.Visual.blindUp = function (element, /* optional */ options) { 1.1405 + /*** 1.1406 + 1.1407 + Blind an element up: change its vertical size to 0. 1.1408 + 1.1409 + ***/ 1.1410 + var d = MochiKit.DOM; 1.1411 + var s = MochiKit.Style; 1.1412 + element = d.getElement(element); 1.1413 + var elementDimensions = s.getElementDimensions(element, true); 1.1414 + var elemClip = s.makeClipping(element); 1.1415 + options = MochiKit.Base.update({ 1.1416 + scaleContent: false, 1.1417 + scaleX: false, 1.1418 + scaleMode: {originalHeight: elementDimensions.h, 1.1419 + originalWidth: elementDimensions.w}, 1.1420 + restoreAfterFinish: true, 1.1421 + afterFinishInternal: function (effect) { 1.1422 + s.hideElement(effect.element); 1.1423 + s.undoClipping(effect.element, elemClip); 1.1424 + } 1.1425 + }, options); 1.1426 + return new MochiKit.Visual.Scale(element, 0, options); 1.1427 +}; 1.1428 + 1.1429 +/** @id MochiKit.Visual.blindDown */ 1.1430 +MochiKit.Visual.blindDown = function (element, /* optional */ options) { 1.1431 + /*** 1.1432 + 1.1433 + Blind an element down: restore its vertical size. 1.1434 + 1.1435 + ***/ 1.1436 + var d = MochiKit.DOM; 1.1437 + var s = MochiKit.Style; 1.1438 + element = d.getElement(element); 1.1439 + var elementDimensions = s.getElementDimensions(element, true); 1.1440 + var elemClip; 1.1441 + options = MochiKit.Base.update({ 1.1442 + scaleContent: false, 1.1443 + scaleX: false, 1.1444 + scaleFrom: 0, 1.1445 + scaleMode: {originalHeight: elementDimensions.h, 1.1446 + originalWidth: elementDimensions.w}, 1.1447 + restoreAfterFinish: true, 1.1448 + afterSetupInternal: function (effect) { 1.1449 + elemClip = s.makeClipping(effect.element); 1.1450 + s.setStyle(effect.element, {height: '0px'}); 1.1451 + s.showElement(effect.element); 1.1452 + }, 1.1453 + afterFinishInternal: function (effect) { 1.1454 + s.undoClipping(effect.element, elemClip); 1.1455 + } 1.1456 + }, options); 1.1457 + return new MochiKit.Visual.Scale(element, 100, options); 1.1458 +}; 1.1459 + 1.1460 +/** @id MochiKit.Visual.switchOff */ 1.1461 +MochiKit.Visual.switchOff = function (element, /* optional */ options) { 1.1462 + /*** 1.1463 + 1.1464 + Apply a switch-off-like effect. 1.1465 + 1.1466 + ***/ 1.1467 + var d = MochiKit.DOM; 1.1468 + var s = MochiKit.Style; 1.1469 + element = d.getElement(element); 1.1470 + var elementDimensions = s.getElementDimensions(element, true); 1.1471 + var oldOpacity = s.getStyle(element, 'opacity'); 1.1472 + var elemClip; 1.1473 + options = MochiKit.Base.update({ 1.1474 + duration: 0.7, 1.1475 + restoreAfterFinish: true, 1.1476 + beforeSetupInternal: function (effect) { 1.1477 + s.makePositioned(element); 1.1478 + elemClip = s.makeClipping(element); 1.1479 + }, 1.1480 + afterFinishInternal: function (effect) { 1.1481 + s.hideElement(element); 1.1482 + s.undoClipping(element, elemClip); 1.1483 + s.undoPositioned(element); 1.1484 + s.setStyle(element, {'opacity': oldOpacity}); 1.1485 + } 1.1486 + }, options); 1.1487 + var v = MochiKit.Visual; 1.1488 + return new v.Sequence( 1.1489 + [new v.appear(element, 1.1490 + { sync: true, duration: 0.57 * options.duration, 1.1491 + from: 0, transition: v.Transitions.flicker }), 1.1492 + new v.Scale(element, 1, 1.1493 + { sync: true, duration: 0.43 * options.duration, 1.1494 + scaleFromCenter: true, scaleX: false, 1.1495 + scaleMode: {originalHeight: elementDimensions.h, 1.1496 + originalWidth: elementDimensions.w}, 1.1497 + scaleContent: false, restoreAfterFinish: true })], 1.1498 + options); 1.1499 +}; 1.1500 + 1.1501 +/** @id MochiKit.Visual.dropOut */ 1.1502 +MochiKit.Visual.dropOut = function (element, /* optional */ options) { 1.1503 + /*** 1.1504 + 1.1505 + Make an element fall and disappear. 1.1506 + 1.1507 + ***/ 1.1508 + var d = MochiKit.DOM; 1.1509 + var s = MochiKit.Style; 1.1510 + element = d.getElement(element); 1.1511 + var oldStyle = { 1.1512 + top: s.getStyle(element, 'top'), 1.1513 + left: s.getStyle(element, 'left'), 1.1514 + opacity: s.getStyle(element, 'opacity') 1.1515 + }; 1.1516 + 1.1517 + options = MochiKit.Base.update({ 1.1518 + duration: 0.5, 1.1519 + distance: 100, 1.1520 + beforeSetupInternal: function (effect) { 1.1521 + s.makePositioned(effect.effects[0].element); 1.1522 + }, 1.1523 + afterFinishInternal: function (effect) { 1.1524 + s.hideElement(effect.effects[0].element); 1.1525 + s.undoPositioned(effect.effects[0].element); 1.1526 + s.setStyle(effect.effects[0].element, oldStyle); 1.1527 + } 1.1528 + }, options); 1.1529 + var v = MochiKit.Visual; 1.1530 + return new v.Parallel( 1.1531 + [new v.Move(element, {x: 0, y: options.distance, sync: true}), 1.1532 + new v.Opacity(element, {sync: true, to: 0.0})], 1.1533 + options); 1.1534 +}; 1.1535 + 1.1536 +/** @id MochiKit.Visual.shake */ 1.1537 +MochiKit.Visual.shake = function (element, /* optional */ options) { 1.1538 + /*** 1.1539 + 1.1540 + Move an element from left to right several times. 1.1541 + 1.1542 + ***/ 1.1543 + var d = MochiKit.DOM; 1.1544 + var v = MochiKit.Visual; 1.1545 + var s = MochiKit.Style; 1.1546 + element = d.getElement(element); 1.1547 + var oldStyle = { 1.1548 + top: s.getStyle(element, 'top'), 1.1549 + left: s.getStyle(element, 'left') 1.1550 + }; 1.1551 + options = MochiKit.Base.update({ 1.1552 + duration: 0.5, 1.1553 + afterFinishInternal: function (effect) { 1.1554 + s.undoPositioned(element); 1.1555 + s.setStyle(element, oldStyle); 1.1556 + } 1.1557 + }, options); 1.1558 + return new v.Sequence( 1.1559 + [new v.Move(element, { sync: true, duration: 0.1 * options.duration, 1.1560 + x: 20, y: 0 }), 1.1561 + new v.Move(element, { sync: true, duration: 0.2 * options.duration, 1.1562 + x: -40, y: 0 }), 1.1563 + new v.Move(element, { sync: true, duration: 0.2 * options.duration, 1.1564 + x: 40, y: 0 }), 1.1565 + new v.Move(element, { sync: true, duration: 0.2 * options.duration, 1.1566 + x: -40, y: 0 }), 1.1567 + new v.Move(element, { sync: true, duration: 0.2 * options.duration, 1.1568 + x: 40, y: 0 }), 1.1569 + new v.Move(element, { sync: true, duration: 0.1 * options.duration, 1.1570 + x: -20, y: 0 })], 1.1571 + options); 1.1572 +}; 1.1573 + 1.1574 +/** @id MochiKit.Visual.slideDown */ 1.1575 +MochiKit.Visual.slideDown = function (element, /* optional */ options) { 1.1576 + /*** 1.1577 + 1.1578 + Slide an element down. 1.1579 + It needs to have the content of the element wrapped in a container 1.1580 + element with fixed height. 1.1581 + 1.1582 + ***/ 1.1583 + var d = MochiKit.DOM; 1.1584 + var b = MochiKit.Base; 1.1585 + var s = MochiKit.Style; 1.1586 + element = d.getElement(element); 1.1587 + if (!element.firstChild) { 1.1588 + throw new Error("MochiKit.Visual.slideDown must be used on a element with a child"); 1.1589 + } 1.1590 + d.removeEmptyTextNodes(element); 1.1591 + var oldInnerBottom = s.getStyle(element.firstChild, 'bottom') || 0; 1.1592 + var elementDimensions = s.getElementDimensions(element, true); 1.1593 + var elemClip; 1.1594 + options = b.update({ 1.1595 + scaleContent: false, 1.1596 + scaleX: false, 1.1597 + scaleFrom: 0, 1.1598 + scaleMode: {originalHeight: elementDimensions.h, 1.1599 + originalWidth: elementDimensions.w}, 1.1600 + restoreAfterFinish: true, 1.1601 + afterSetupInternal: function (effect) { 1.1602 + s.makePositioned(effect.element); 1.1603 + s.makePositioned(effect.element.firstChild); 1.1604 + if (/Opera/.test(navigator.userAgent)) { 1.1605 + s.setStyle(effect.element, {top: ''}); 1.1606 + } 1.1607 + elemClip = s.makeClipping(effect.element); 1.1608 + s.setStyle(effect.element, {height: '0px'}); 1.1609 + s.showElement(effect.element); 1.1610 + }, 1.1611 + afterUpdateInternal: function (effect) { 1.1612 + var elementDimensions = s.getElementDimensions(effect.element, true); 1.1613 + s.setStyle(effect.element.firstChild, 1.1614 + {bottom: (effect.dims[0] - elementDimensions.h) + 'px'}); 1.1615 + }, 1.1616 + afterFinishInternal: function (effect) { 1.1617 + s.undoClipping(effect.element, elemClip); 1.1618 + // IE will crash if child is undoPositioned first 1.1619 + if (/MSIE/.test(navigator.userAgent)) { 1.1620 + s.undoPositioned(effect.element); 1.1621 + s.undoPositioned(effect.element.firstChild); 1.1622 + } else { 1.1623 + s.undoPositioned(effect.element.firstChild); 1.1624 + s.undoPositioned(effect.element); 1.1625 + } 1.1626 + s.setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); 1.1627 + } 1.1628 + }, options); 1.1629 + 1.1630 + return new MochiKit.Visual.Scale(element, 100, options); 1.1631 +}; 1.1632 + 1.1633 +/** @id MochiKit.Visual.slideUp */ 1.1634 +MochiKit.Visual.slideUp = function (element, /* optional */ options) { 1.1635 + /*** 1.1636 + 1.1637 + Slide an element up. 1.1638 + It needs to have the content of the element wrapped in a container 1.1639 + element with fixed height. 1.1640 + 1.1641 + ***/ 1.1642 + var d = MochiKit.DOM; 1.1643 + var b = MochiKit.Base; 1.1644 + var s = MochiKit.Style; 1.1645 + element = d.getElement(element); 1.1646 + if (!element.firstChild) { 1.1647 + throw new Error("MochiKit.Visual.slideUp must be used on a element with a child"); 1.1648 + } 1.1649 + d.removeEmptyTextNodes(element); 1.1650 + var oldInnerBottom = s.getStyle(element.firstChild, 'bottom'); 1.1651 + var elementDimensions = s.getElementDimensions(element, true); 1.1652 + var elemClip; 1.1653 + options = b.update({ 1.1654 + scaleContent: false, 1.1655 + scaleX: false, 1.1656 + scaleMode: {originalHeight: elementDimensions.h, 1.1657 + originalWidth: elementDimensions.w}, 1.1658 + scaleFrom: 100, 1.1659 + restoreAfterFinish: true, 1.1660 + beforeStartInternal: function (effect) { 1.1661 + s.makePositioned(effect.element); 1.1662 + s.makePositioned(effect.element.firstChild); 1.1663 + if (/Opera/.test(navigator.userAgent)) { 1.1664 + s.setStyle(effect.element, {top: ''}); 1.1665 + } 1.1666 + elemClip = s.makeClipping(effect.element); 1.1667 + s.showElement(effect.element); 1.1668 + }, 1.1669 + afterUpdateInternal: function (effect) { 1.1670 + var elementDimensions = s.getElementDimensions(effect.element, true); 1.1671 + s.setStyle(effect.element.firstChild, 1.1672 + {bottom: (effect.dims[0] - elementDimensions.h) + 'px'}); 1.1673 + }, 1.1674 + afterFinishInternal: function (effect) { 1.1675 + s.hideElement(effect.element); 1.1676 + s.undoClipping(effect.element, elemClip); 1.1677 + s.undoPositioned(effect.element.firstChild); 1.1678 + s.undoPositioned(effect.element); 1.1679 + s.setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); 1.1680 + } 1.1681 + }, options); 1.1682 + return new MochiKit.Visual.Scale(element, 0, options); 1.1683 +}; 1.1684 + 1.1685 +// Bug in opera makes the TD containing this element expand for a instance 1.1686 +// after finish 1.1687 +/** @id MochiKit.Visual.squish */ 1.1688 +MochiKit.Visual.squish = function (element, /* optional */ options) { 1.1689 + /*** 1.1690 + 1.1691 + Reduce an element and make it disappear. 1.1692 + 1.1693 + ***/ 1.1694 + var d = MochiKit.DOM; 1.1695 + var b = MochiKit.Base; 1.1696 + var s = MochiKit.Style; 1.1697 + var elementDimensions = s.getElementDimensions(element, true); 1.1698 + var elemClip; 1.1699 + options = b.update({ 1.1700 + restoreAfterFinish: true, 1.1701 + scaleMode: {originalHeight: elementDimensions.w, 1.1702 + originalWidth: elementDimensions.h}, 1.1703 + beforeSetupInternal: function (effect) { 1.1704 + elemClip = s.makeClipping(effect.element); 1.1705 + }, 1.1706 + afterFinishInternal: function (effect) { 1.1707 + s.hideElement(effect.element); 1.1708 + s.undoClipping(effect.element, elemClip); 1.1709 + } 1.1710 + }, options); 1.1711 + 1.1712 + return new MochiKit.Visual.Scale(element, /Opera/.test(navigator.userAgent) ? 1 : 0, options); 1.1713 +}; 1.1714 + 1.1715 +/** @id MochiKit.Visual.grow */ 1.1716 +MochiKit.Visual.grow = function (element, /* optional */ options) { 1.1717 + /*** 1.1718 + 1.1719 + Grow an element to its original size. Make it zero-sized before 1.1720 + if necessary. 1.1721 + 1.1722 + ***/ 1.1723 + var d = MochiKit.DOM; 1.1724 + var v = MochiKit.Visual; 1.1725 + var s = MochiKit.Style; 1.1726 + element = d.getElement(element); 1.1727 + options = MochiKit.Base.update({ 1.1728 + direction: 'center', 1.1729 + moveTransition: v.Transitions.sinoidal, 1.1730 + scaleTransition: v.Transitions.sinoidal, 1.1731 + opacityTransition: v.Transitions.full, 1.1732 + scaleContent: true, 1.1733 + scaleFromCenter: false 1.1734 + }, options); 1.1735 + var oldStyle = { 1.1736 + top: element.style.top, 1.1737 + left: element.style.left, 1.1738 + height: element.style.height, 1.1739 + width: element.style.width, 1.1740 + opacity: s.getStyle(element, 'opacity') 1.1741 + }; 1.1742 + var dims = s.getElementDimensions(element, true); 1.1743 + var initialMoveX, initialMoveY; 1.1744 + var moveX, moveY; 1.1745 + 1.1746 + switch (options.direction) { 1.1747 + case 'top-left': 1.1748 + initialMoveX = initialMoveY = moveX = moveY = 0; 1.1749 + break; 1.1750 + case 'top-right': 1.1751 + initialMoveX = dims.w; 1.1752 + initialMoveY = moveY = 0; 1.1753 + moveX = -dims.w; 1.1754 + break; 1.1755 + case 'bottom-left': 1.1756 + initialMoveX = moveX = 0; 1.1757 + initialMoveY = dims.h; 1.1758 + moveY = -dims.h; 1.1759 + break; 1.1760 + case 'bottom-right': 1.1761 + initialMoveX = dims.w; 1.1762 + initialMoveY = dims.h; 1.1763 + moveX = -dims.w; 1.1764 + moveY = -dims.h; 1.1765 + break; 1.1766 + case 'center': 1.1767 + initialMoveX = dims.w / 2; 1.1768 + initialMoveY = dims.h / 2; 1.1769 + moveX = -dims.w / 2; 1.1770 + moveY = -dims.h / 2; 1.1771 + break; 1.1772 + } 1.1773 + 1.1774 + var optionsParallel = MochiKit.Base.update({ 1.1775 + beforeSetupInternal: function (effect) { 1.1776 + s.setStyle(effect.effects[0].element, {height: '0px'}); 1.1777 + s.showElement(effect.effects[0].element); 1.1778 + }, 1.1779 + afterFinishInternal: function (effect) { 1.1780 + s.undoClipping(effect.effects[0].element); 1.1781 + s.undoPositioned(effect.effects[0].element); 1.1782 + s.setStyle(effect.effects[0].element, oldStyle); 1.1783 + } 1.1784 + }, options); 1.1785 + 1.1786 + return new v.Move(element, { 1.1787 + x: initialMoveX, 1.1788 + y: initialMoveY, 1.1789 + duration: 0.01, 1.1790 + beforeSetupInternal: function (effect) { 1.1791 + s.hideElement(effect.element); 1.1792 + s.makeClipping(effect.element); 1.1793 + s.makePositioned(effect.element); 1.1794 + }, 1.1795 + afterFinishInternal: function (effect) { 1.1796 + new v.Parallel( 1.1797 + [new v.Opacity(effect.element, { 1.1798 + sync: true, to: 1.0, from: 0.0, 1.1799 + transition: options.opacityTransition 1.1800 + }), 1.1801 + new v.Move(effect.element, { 1.1802 + x: moveX, y: moveY, sync: true, 1.1803 + transition: options.moveTransition 1.1804 + }), 1.1805 + new v.Scale(effect.element, 100, { 1.1806 + scaleMode: {originalHeight: dims.h, 1.1807 + originalWidth: dims.w}, 1.1808 + sync: true, 1.1809 + scaleFrom: /Opera/.test(navigator.userAgent) ? 1 : 0, 1.1810 + transition: options.scaleTransition, 1.1811 + scaleContent: options.scaleContent, 1.1812 + scaleFromCenter: options.scaleFromCenter, 1.1813 + restoreAfterFinish: true 1.1814 + }) 1.1815 + ], optionsParallel 1.1816 + ); 1.1817 + } 1.1818 + }); 1.1819 +}; 1.1820 + 1.1821 +/** @id MochiKit.Visual.shrink */ 1.1822 +MochiKit.Visual.shrink = function (element, /* optional */ options) { 1.1823 + /*** 1.1824 + 1.1825 + Shrink an element and make it disappear. 1.1826 + 1.1827 + ***/ 1.1828 + var d = MochiKit.DOM; 1.1829 + var v = MochiKit.Visual; 1.1830 + var s = MochiKit.Style; 1.1831 + element = d.getElement(element); 1.1832 + options = MochiKit.Base.update({ 1.1833 + direction: 'center', 1.1834 + moveTransition: v.Transitions.sinoidal, 1.1835 + scaleTransition: v.Transitions.sinoidal, 1.1836 + opacityTransition: v.Transitions.none, 1.1837 + scaleContent: true, 1.1838 + scaleFromCenter: false 1.1839 + }, options); 1.1840 + var oldStyle = { 1.1841 + top: element.style.top, 1.1842 + left: element.style.left, 1.1843 + height: element.style.height, 1.1844 + width: element.style.width, 1.1845 + opacity: s.getStyle(element, 'opacity') 1.1846 + }; 1.1847 + 1.1848 + var dims = s.getElementDimensions(element, true); 1.1849 + var moveX, moveY; 1.1850 + 1.1851 + switch (options.direction) { 1.1852 + case 'top-left': 1.1853 + moveX = moveY = 0; 1.1854 + break; 1.1855 + case 'top-right': 1.1856 + moveX = dims.w; 1.1857 + moveY = 0; 1.1858 + break; 1.1859 + case 'bottom-left': 1.1860 + moveX = 0; 1.1861 + moveY = dims.h; 1.1862 + break; 1.1863 + case 'bottom-right': 1.1864 + moveX = dims.w; 1.1865 + moveY = dims.h; 1.1866 + break; 1.1867 + case 'center': 1.1868 + moveX = dims.w / 2; 1.1869 + moveY = dims.h / 2; 1.1870 + break; 1.1871 + } 1.1872 + var elemClip; 1.1873 + 1.1874 + var optionsParallel = MochiKit.Base.update({ 1.1875 + beforeStartInternal: function (effect) { 1.1876 + s.makePositioned(effect.effects[0].element); 1.1877 + elemClip = s.makeClipping(effect.effects[0].element); 1.1878 + }, 1.1879 + afterFinishInternal: function (effect) { 1.1880 + s.hideElement(effect.effects[0].element); 1.1881 + s.undoClipping(effect.effects[0].element, elemClip); 1.1882 + s.undoPositioned(effect.effects[0].element); 1.1883 + s.setStyle(effect.effects[0].element, oldStyle); 1.1884 + } 1.1885 + }, options); 1.1886 + 1.1887 + return new v.Parallel( 1.1888 + [new v.Opacity(element, { 1.1889 + sync: true, to: 0.0, from: 1.0, 1.1890 + transition: options.opacityTransition 1.1891 + }), 1.1892 + new v.Scale(element, /Opera/.test(navigator.userAgent) ? 1 : 0, { 1.1893 + scaleMode: {originalHeight: dims.h, originalWidth: dims.w}, 1.1894 + sync: true, transition: options.scaleTransition, 1.1895 + scaleContent: options.scaleContent, 1.1896 + scaleFromCenter: options.scaleFromCenter, 1.1897 + restoreAfterFinish: true 1.1898 + }), 1.1899 + new v.Move(element, { 1.1900 + x: moveX, y: moveY, sync: true, transition: options.moveTransition 1.1901 + }) 1.1902 + ], optionsParallel 1.1903 + ); 1.1904 +}; 1.1905 + 1.1906 +/** @id MochiKit.Visual.pulsate */ 1.1907 +MochiKit.Visual.pulsate = function (element, /* optional */ options) { 1.1908 + /*** 1.1909 + 1.1910 + Pulse an element between appear/fade. 1.1911 + 1.1912 + ***/ 1.1913 + var d = MochiKit.DOM; 1.1914 + var v = MochiKit.Visual; 1.1915 + var b = MochiKit.Base; 1.1916 + var oldOpacity = MochiKit.Style.getStyle(element, 'opacity'); 1.1917 + options = b.update({ 1.1918 + duration: 3.0, 1.1919 + from: 0, 1.1920 + afterFinishInternal: function (effect) { 1.1921 + MochiKit.Style.setStyle(effect.element, {'opacity': oldOpacity}); 1.1922 + } 1.1923 + }, options); 1.1924 + var transition = options.transition || v.Transitions.sinoidal; 1.1925 + options.transition = function (pos) { 1.1926 + return transition(1 - v.Transitions.pulse(pos, options.pulses)); 1.1927 + }; 1.1928 + return new v.Opacity(element, options); 1.1929 +}; 1.1930 + 1.1931 +/** @id MochiKit.Visual.fold */ 1.1932 +MochiKit.Visual.fold = function (element, /* optional */ options) { 1.1933 + /*** 1.1934 + 1.1935 + Fold an element, first vertically, then horizontally. 1.1936 + 1.1937 + ***/ 1.1938 + var d = MochiKit.DOM; 1.1939 + var v = MochiKit.Visual; 1.1940 + var s = MochiKit.Style; 1.1941 + element = d.getElement(element); 1.1942 + var elementDimensions = s.getElementDimensions(element, true); 1.1943 + var oldStyle = { 1.1944 + top: element.style.top, 1.1945 + left: element.style.left, 1.1946 + width: element.style.width, 1.1947 + height: element.style.height 1.1948 + }; 1.1949 + var elemClip = s.makeClipping(element); 1.1950 + options = MochiKit.Base.update({ 1.1951 + scaleContent: false, 1.1952 + scaleX: false, 1.1953 + scaleMode: {originalHeight: elementDimensions.h, 1.1954 + originalWidth: elementDimensions.w}, 1.1955 + afterFinishInternal: function (effect) { 1.1956 + new v.Scale(element, 1, { 1.1957 + scaleContent: false, 1.1958 + scaleY: false, 1.1959 + scaleMode: {originalHeight: elementDimensions.h, 1.1960 + originalWidth: elementDimensions.w}, 1.1961 + afterFinishInternal: function (effect) { 1.1962 + s.hideElement(effect.element); 1.1963 + s.undoClipping(effect.element, elemClip); 1.1964 + s.setStyle(effect.element, oldStyle); 1.1965 + } 1.1966 + }); 1.1967 + } 1.1968 + }, options); 1.1969 + return new v.Scale(element, 5, options); 1.1970 +}; 1.1971 + 1.1972 + 1.1973 +// Compatibility with MochiKit 1.0 1.1974 +MochiKit.Visual.Color = MochiKit.Color.Color; 1.1975 +MochiKit.Visual.getElementsComputedStyle = MochiKit.DOM.computedStyle; 1.1976 + 1.1977 +/* end of Rico adaptation */ 1.1978 + 1.1979 +MochiKit.Visual.__new__ = function () { 1.1980 + var m = MochiKit.Base; 1.1981 + 1.1982 + m.nameFunctions(this); 1.1983 + 1.1984 + this.EXPORT_TAGS = { 1.1985 + ":common": this.EXPORT, 1.1986 + ":all": m.concat(this.EXPORT, this.EXPORT_OK) 1.1987 + }; 1.1988 + 1.1989 +}; 1.1990 + 1.1991 +MochiKit.Visual.EXPORT = [ 1.1992 + "roundElement", 1.1993 + "roundClass", 1.1994 + "tagifyText", 1.1995 + "multiple", 1.1996 + "toggle", 1.1997 + "Parallel", 1.1998 + "Sequence", 1.1999 + "Opacity", 1.2000 + "Move", 1.2001 + "Scale", 1.2002 + "Highlight", 1.2003 + "ScrollTo", 1.2004 + "Morph", 1.2005 + "fade", 1.2006 + "appear", 1.2007 + "puff", 1.2008 + "blindUp", 1.2009 + "blindDown", 1.2010 + "switchOff", 1.2011 + "dropOut", 1.2012 + "shake", 1.2013 + "slideDown", 1.2014 + "slideUp", 1.2015 + "squish", 1.2016 + "grow", 1.2017 + "shrink", 1.2018 + "pulsate", 1.2019 + "fold" 1.2020 +]; 1.2021 + 1.2022 +MochiKit.Visual.EXPORT_OK = [ 1.2023 + "Base", 1.2024 + "PAIRS" 1.2025 +]; 1.2026 + 1.2027 +MochiKit.Visual.__new__(); 1.2028 + 1.2029 +MochiKit.Base._exportSymbols(this, MochiKit.Visual);