Diffstat (limited to 'frontend/gamma/js/MochiKit/Visual.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/gamma/js/MochiKit/Visual.js | 1975 |
1 files changed, 1975 insertions, 0 deletions
diff --git a/frontend/gamma/js/MochiKit/Visual.js b/frontend/gamma/js/MochiKit/Visual.js new file mode 100644 index 0000000..648d82a --- a/dev/null +++ b/frontend/gamma/js/MochiKit/Visual.js | |||
@@ -0,0 +1,1975 @@ | |||
1 | /*** | ||
2 | |||
3 | MochiKit.Visual 1.5 | ||
4 | |||
5 | See <http://mochikit.com/> for documentation, downloads, license, etc. | ||
6 | |||
7 | (c) 2005 Bob Ippolito and others. All rights Reserved. | ||
8 | |||
9 | ***/ | ||
10 | |||
11 | MochiKit.Base._module('Visual', '1.5', ['Base', 'DOM', 'Style', 'Color', 'Position']); | ||
12 | |||
13 | MochiKit.Visual._RoundCorners = function (e, options) { | ||
14 | e = MochiKit.DOM.getElement(e); | ||
15 | this._setOptions(options); | ||
16 | if (this.options.__unstable__wrapElement) { | ||
17 | e = this._doWrap(e); | ||
18 | } | ||
19 | |||
20 | var color = this.options.color; | ||
21 | var C = MochiKit.Color.Color; | ||
22 | if (this.options.color === "fromElement") { | ||
23 | color = C.fromBackground(e); | ||
24 | } else if (!(color instanceof C)) { | ||
25 | color = C.fromString(color); | ||
26 | } | ||
27 | this.isTransparent = (color.asRGB().a <= 0); | ||
28 | |||
29 | var bgColor = this.options.bgColor; | ||
30 | if (this.options.bgColor === "fromParent") { | ||
31 | bgColor = C.fromBackground(e.offsetParent); | ||
32 | } else if (!(bgColor instanceof C)) { | ||
33 | bgColor = C.fromString(bgColor); | ||
34 | } | ||
35 | |||
36 | this._roundCornersImpl(e, color, bgColor); | ||
37 | }; | ||
38 | |||
39 | MochiKit.Visual._RoundCorners.prototype = { | ||
40 | _doWrap: function (e) { | ||
41 | var parent = e.parentNode; | ||
42 | var doc = MochiKit.DOM.currentDocument(); | ||
43 | if (typeof(doc.defaultView) === "undefined" | ||
44 | || doc.defaultView === null) { | ||
45 | return e; | ||
46 | } | ||
47 | var style = doc.defaultView.getComputedStyle(e, null); | ||
48 | if (typeof(style) === "undefined" || style === null) { | ||
49 | return e; | ||
50 | } | ||
51 | var wrapper = MochiKit.DOM.DIV({"style": { | ||
52 | display: "block", | ||
53 | // convert padding to margin | ||
54 | marginTop: style.getPropertyValue("padding-top"), | ||
55 | marginRight: style.getPropertyValue("padding-right"), | ||
56 | marginBottom: style.getPropertyValue("padding-bottom"), | ||
57 | marginLeft: style.getPropertyValue("padding-left"), | ||
58 | // remove padding so the rounding looks right | ||
59 | padding: "0px" | ||
60 | /* | ||
61 | paddingRight: "0px", | ||
62 | paddingLeft: "0px" | ||
63 | */ | ||
64 | }}); | ||
65 | wrapper.innerHTML = e.innerHTML; | ||
66 | e.innerHTML = ""; | ||
67 | e.appendChild(wrapper); | ||
68 | return e; | ||
69 | }, | ||
70 | |||
71 | _roundCornersImpl: function (e, color, bgColor) { | ||
72 | if (this.options.border) { | ||
73 | this._renderBorder(e, bgColor); | ||
74 | } | ||
75 | if (this._isTopRounded()) { | ||
76 | this._roundTopCorners(e, color, bgColor); | ||
77 | } | ||
78 | if (this._isBottomRounded()) { | ||
79 | this._roundBottomCorners(e, color, bgColor); | ||
80 | } | ||
81 | }, | ||
82 | |||
83 | _renderBorder: function (el, bgColor) { | ||
84 | var borderValue = "1px solid " + this._borderColor(bgColor); | ||
85 | var borderL = "border-left: " + borderValue; | ||
86 | var borderR = "border-right: " + borderValue; | ||
87 | var style = "style='" + borderL + ";" + borderR + "'"; | ||
88 | el.innerHTML = "<div " + style + ">" + el.innerHTML + "</div>"; | ||
89 | }, | ||
90 | |||
91 | _roundTopCorners: function (el, color, bgColor) { | ||
92 | var corner = this._createCorner(bgColor); | ||
93 | for (var i = 0; i < this.options.numSlices; i++) { | ||
94 | corner.appendChild( | ||
95 | this._createCornerSlice(color, bgColor, i, "top") | ||
96 | ); | ||
97 | } | ||
98 | el.style.paddingTop = 0; | ||
99 | el.insertBefore(corner, el.firstChild); | ||
100 | }, | ||
101 | |||
102 | _roundBottomCorners: function (el, color, bgColor) { | ||
103 | var corner = this._createCorner(bgColor); | ||
104 | for (var i = (this.options.numSlices - 1); i >= 0; i--) { | ||
105 | corner.appendChild( | ||
106 | this._createCornerSlice(color, bgColor, i, "bottom") | ||
107 | ); | ||
108 | } | ||
109 | el.style.paddingBottom = 0; | ||
110 | el.appendChild(corner); | ||
111 | }, | ||
112 | |||
113 | _createCorner: function (bgColor) { | ||
114 | var dom = MochiKit.DOM; | ||
115 | return dom.DIV({style: {backgroundColor: bgColor.toString()}}); | ||
116 | }, | ||
117 | |||
118 | _createCornerSlice: function (color, bgColor, n, position) { | ||
119 | var slice = MochiKit.DOM.SPAN(); | ||
120 | |||
121 | var inStyle = slice.style; | ||
122 | inStyle.backgroundColor = color.toString(); | ||
123 | inStyle.display = "block"; | ||
124 | inStyle.height = "1px"; | ||
125 | inStyle.overflow = "hidden"; | ||
126 | inStyle.fontSize = "1px"; | ||
127 | |||
128 | var borderColor = this._borderColor(color, bgColor); | ||
129 | if (this.options.border && n === 0) { | ||
130 | inStyle.borderTopStyle = "solid"; | ||
131 | inStyle.borderTopWidth = "1px"; | ||
132 | inStyle.borderLeftWidth = "0px"; | ||
133 | inStyle.borderRightWidth = "0px"; | ||
134 | inStyle.borderBottomWidth = "0px"; | ||
135 | // assumes css compliant box model | ||
136 | inStyle.height = "0px"; | ||
137 | inStyle.borderColor = borderColor.toString(); | ||
138 | } else if (borderColor) { | ||
139 | inStyle.borderColor = borderColor.toString(); | ||
140 | inStyle.borderStyle = "solid"; | ||
141 | inStyle.borderWidth = "0px 1px"; | ||
142 | } | ||
143 | |||
144 | if (!this.options.compact && (n == (this.options.numSlices - 1))) { | ||
145 | inStyle.height = "2px"; | ||
146 | } | ||
147 | |||
148 | this._setMargin(slice, n, position); | ||
149 | this._setBorder(slice, n, position); | ||
150 | |||
151 | return slice; | ||
152 | }, | ||
153 | |||
154 | _setOptions: function (options) { | ||
155 | this.options = { | ||
156 | corners: "all", | ||
157 | color: "fromElement", | ||
158 | bgColor: "fromParent", | ||
159 | blend: true, | ||
160 | border: false, | ||
161 | compact: false, | ||
162 | __unstable__wrapElement: false | ||
163 | }; | ||
164 | MochiKit.Base.update(this.options, options); | ||
165 | |||
166 | this.options.numSlices = (this.options.compact ? 2 : 4); | ||
167 | }, | ||
168 | |||
169 | _whichSideTop: function () { | ||
170 | var corners = this.options.corners; | ||
171 | if (this._hasString(corners, "all", "top")) { | ||
172 | return ""; | ||
173 | } | ||
174 | |||
175 | var has_tl = (corners.indexOf("tl") != -1); | ||
176 | var has_tr = (corners.indexOf("tr") != -1); | ||
177 | if (has_tl && has_tr) { | ||
178 | return ""; | ||
179 | } | ||
180 | if (has_tl) { | ||
181 | return "left"; | ||
182 | } | ||
183 | if (has_tr) { | ||
184 | return "right"; | ||
185 | } | ||
186 | return ""; | ||
187 | }, | ||
188 | |||
189 | _whichSideBottom: function () { | ||
190 | var corners = this.options.corners; | ||
191 | if (this._hasString(corners, "all", "bottom")) { | ||
192 | return ""; | ||
193 | } | ||
194 | |||
195 | var has_bl = (corners.indexOf('bl') != -1); | ||
196 | var has_br = (corners.indexOf('br') != -1); | ||
197 | if (has_bl && has_br) { | ||
198 | return ""; | ||
199 | } | ||
200 | if (has_bl) { | ||
201 | return "left"; | ||
202 | } | ||
203 | if (has_br) { | ||
204 | return "right"; | ||
205 | } | ||
206 | return ""; | ||
207 | }, | ||
208 | |||
209 | _borderColor: function (color, bgColor) { | ||
210 | if (color == "transparent") { | ||
211 | return bgColor; | ||
212 | } else if (this.options.border) { | ||
213 | return this.options.border; | ||
214 | } else if (this.options.blend) { | ||
215 | return bgColor.blendedColor(color); | ||
216 | } | ||
217 | return ""; | ||
218 | }, | ||
219 | |||
220 | |||
221 | _setMargin: function (el, n, corners) { | ||
222 | var marginSize = this._marginSize(n) + "px"; | ||
223 | var whichSide = ( | ||
224 | corners == "top" ? this._whichSideTop() : this._whichSideBottom() | ||
225 | ); | ||
226 | var style = el.style; | ||
227 | |||
228 | if (whichSide == "left") { | ||
229 | style.marginLeft = marginSize; | ||
230 | style.marginRight = "0px"; | ||
231 | } else if (whichSide == "right") { | ||
232 | style.marginRight = marginSize; | ||
233 | style.marginLeft = "0px"; | ||
234 | } else { | ||
235 | style.marginLeft = marginSize; | ||
236 | style.marginRight = marginSize; | ||
237 | } | ||
238 | }, | ||
239 | |||
240 | _setBorder: function (el, n, corners) { | ||
241 | var borderSize = this._borderSize(n) + "px"; | ||
242 | var whichSide = ( | ||
243 | corners == "top" ? this._whichSideTop() : this._whichSideBottom() | ||
244 | ); | ||
245 | |||
246 | var style = el.style; | ||
247 | if (whichSide == "left") { | ||
248 | style.borderLeftWidth = borderSize; | ||
249 | style.borderRightWidth = "0px"; | ||
250 | } else if (whichSide == "right") { | ||
251 | style.borderRightWidth = borderSize; | ||
252 | style.borderLeftWidth = "0px"; | ||
253 | } else { | ||
254 | style.borderLeftWidth = borderSize; | ||
255 | style.borderRightWidth = borderSize; | ||
256 | } | ||
257 | }, | ||
258 | |||
259 | _marginSize: function (n) { | ||
260 | if (this.isTransparent) { | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | var o = this.options; | ||
265 | if (o.compact && o.blend) { | ||
266 | var smBlendedMarginSizes = [1, 0]; | ||
267 | return smBlendedMarginSizes[n]; | ||
268 | } else if (o.compact) { | ||
269 | var compactMarginSizes = [2, 1]; | ||
270 | return compactMarginSizes[n]; | ||
271 | } else if (o.blend) { | ||
272 | var blendedMarginSizes = [3, 2, 1, 0]; | ||
273 | return blendedMarginSizes[n]; | ||
274 | } else { | ||
275 | var marginSizes = [5, 3, 2, 1]; | ||
276 | return marginSizes[n]; | ||
277 | } | ||
278 | }, | ||
279 | |||
280 | _borderSize: function (n) { | ||
281 | var o = this.options; | ||
282 | var borderSizes; | ||
283 | if (o.compact && (o.blend || this.isTransparent)) { | ||
284 | return 1; | ||
285 | } else if (o.compact) { | ||
286 | borderSizes = [1, 0]; | ||
287 | } else if (o.blend) { | ||
288 | borderSizes = [2, 1, 1, 1]; | ||
289 | } else if (o.border) { | ||
290 | borderSizes = [0, 2, 0, 0]; | ||
291 | } else if (this.isTransparent) { | ||
292 | borderSizes = [5, 3, 2, 1]; | ||
293 | } else { | ||
294 | return 0; | ||
295 | } | ||
296 | return borderSizes[n]; | ||
297 | }, | ||
298 | |||
299 | _hasString: function (str) { | ||
300 | for (var i = 1; i< arguments.length; i++) { | ||
301 | if (str.indexOf(arguments[i]) != -1) { | ||
302 | return true; | ||
303 | } | ||
304 | } | ||
305 | return false; | ||
306 | }, | ||
307 | |||
308 | _isTopRounded: function () { | ||
309 | return this._hasString(this.options.corners, | ||
310 | "all", "top", "tl", "tr" | ||
311 | ); | ||
312 | }, | ||
313 | |||
314 | _isBottomRounded: function () { | ||
315 | return this._hasString(this.options.corners, | ||
316 | "all", "bottom", "bl", "br" | ||
317 | ); | ||
318 | }, | ||
319 | |||
320 | _hasSingleTextChild: function (el) { | ||
321 | return (el.childNodes.length == 1 && el.childNodes[0].nodeType == 3); | ||
322 | } | ||
323 | }; | ||
324 | |||
325 | /** @id MochiKit.Visual.roundElement */ | ||
326 | MochiKit.Visual.roundElement = function (e, options) { | ||
327 | new MochiKit.Visual._RoundCorners(e, options); | ||
328 | }; | ||
329 | |||
330 | /** @id MochiKit.Visual.roundClass */ | ||
331 | MochiKit.Visual.roundClass = function (tagName, className, options) { | ||
332 | var elements = MochiKit.DOM.getElementsByTagAndClassName( | ||
333 | tagName, className | ||
334 | ); | ||
335 | for (var i = 0; i < elements.length; i++) { | ||
336 | MochiKit.Visual.roundElement(elements[i], options); | ||
337 | } | ||
338 | }; | ||
339 | |||
340 | /** @id MochiKit.Visual.tagifyText */ | ||
341 | MochiKit.Visual.tagifyText = function (element, /* optional */tagifyStyle) { | ||
342 | /*** | ||
343 | |||
344 | Change a node text to character in tags. | ||
345 | |||
346 | @param tagifyStyle: the style to apply to character nodes, default to | ||
347 | 'position: relative'. | ||
348 | |||
349 | ***/ | ||
350 | tagifyStyle = tagifyStyle || 'position:relative'; | ||
351 | if (/MSIE/.test(navigator.userAgent)) { | ||
352 | tagifyStyle += ';zoom:1'; | ||
353 | } | ||
354 | element = MochiKit.DOM.getElement(element); | ||
355 | var ma = MochiKit.Base.map; | ||
356 | ma(function (child) { | ||
357 | if (child.nodeType == 3) { | ||
358 | ma(function (character) { | ||
359 | element.insertBefore( | ||
360 | MochiKit.DOM.SPAN({style: tagifyStyle}, | ||
361 | character == ' ' ? String.fromCharCode(160) : character), child); | ||
362 | }, child.nodeValue.split('')); | ||
363 | MochiKit.DOM.removeElement(child); | ||
364 | } | ||
365 | }, element.childNodes); | ||
366 | }; | ||
367 | |||
368 | MochiKit.Visual._forceRerendering = function (element) { | ||
369 | try { | ||
370 | element = MochiKit.DOM.getElement(element); | ||
371 | var n = document.createTextNode(' '); | ||
372 | element.appendChild(n); | ||
373 | element.removeChild(n); | ||
374 | } catch(e) { | ||
375 | } | ||
376 | }; | ||
377 | |||
378 | /** @id MochiKit.Visual.multiple */ | ||
379 | MochiKit.Visual.multiple = function (elements, effect, /* optional */options) { | ||
380 | /*** | ||
381 | |||
382 | Launch the same effect subsequently on given elements. | ||
383 | |||
384 | ***/ | ||
385 | options = MochiKit.Base.update({ | ||
386 | speed: 0.1, delay: 0.0 | ||
387 | }, options); | ||
388 | var masterDelay = options.delay; | ||
389 | var index = 0; | ||
390 | MochiKit.Base.map(function (innerelement) { | ||
391 | options.delay = index * options.speed + masterDelay; | ||
392 | new effect(innerelement, options); | ||
393 | index += 1; | ||
394 | }, elements); | ||
395 | }; | ||
396 | |||
397 | MochiKit.Visual.PAIRS = { | ||
398 | 'slide': ['slideDown', 'slideUp'], | ||
399 | 'blind': ['blindDown', 'blindUp'], | ||
400 | 'appear': ['appear', 'fade'], | ||
401 | 'size': ['grow', 'shrink'] | ||
402 | }; | ||
403 | |||
404 | /** @id MochiKit.Visual.toggle */ | ||
405 | MochiKit.Visual.toggle = function (element, /* optional */effect, /* optional */options) { | ||
406 | /*** | ||
407 | |||
408 | Toggle an item between two state depending of its visibility, making | ||
409 | a effect between these states. Default effect is 'appear', can be | ||
410 | 'slide' or 'blind'. | ||
411 | |||
412 | ***/ | ||
413 | element = MochiKit.DOM.getElement(element); | ||
414 | effect = (effect || 'appear').toLowerCase(); | ||
415 | options = MochiKit.Base.update({ | ||
416 | queue: {position: 'end', scope: (element.id || 'global'), limit: 1} | ||
417 | }, options); | ||
418 | var v = MochiKit.Visual; | ||
419 | v[MochiKit.Style.getStyle(element, 'display') != 'none' ? | ||
420 | v.PAIRS[effect][1] : v.PAIRS[effect][0]](element, options); | ||
421 | }; | ||
422 | |||
423 | /*** | ||
424 | |||
425 | Transitions: define functions calculating variations depending of a position. | ||
426 | |||
427 | ***/ | ||
428 | |||
429 | MochiKit.Visual.Transitions = { __export__: false }; | ||
430 | |||
431 | /** @id MochiKit.Visual.Transitions.linear */ | ||
432 | MochiKit.Visual.Transitions.linear = function (pos) { | ||
433 | return pos; | ||
434 | }; | ||
435 | |||
436 | /** @id MochiKit.Visual.Transitions.sinoidal */ | ||
437 | MochiKit.Visual.Transitions.sinoidal = function (pos) { | ||
438 | return 0.5 - Math.cos(pos*Math.PI)/2; | ||
439 | }; | ||
440 | |||
441 | /** @id MochiKit.Visual.Transitions.reverse */ | ||
442 | MochiKit.Visual.Transitions.reverse = function (pos) { | ||
443 | return 1 - pos; | ||
444 | }; | ||
445 | |||
446 | /** @id MochiKit.Visual.Transitions.flicker */ | ||
447 | MochiKit.Visual.Transitions.flicker = function (pos) { | ||
448 | return 0.25 - Math.cos(pos*Math.PI)/4 + Math.random()/2; | ||
449 | }; | ||
450 | |||
451 | /** @id MochiKit.Visual.Transitions.wobble */ | ||
452 | MochiKit.Visual.Transitions.wobble = function (pos) { | ||
453 | return 0.5 - Math.cos(9*pos*Math.PI)/2; | ||
454 | }; | ||
455 | |||
456 | /** @id MochiKit.Visual.Transitions.pulse */ | ||
457 | MochiKit.Visual.Transitions.pulse = function (pos, pulses) { | ||
458 | if (pulses) { | ||
459 | pos *= 2 * pulses; | ||
460 | } else { | ||
461 | pos *= 10; | ||
462 | } | ||
463 | var decimals = pos - Math.floor(pos); | ||
464 | return (Math.floor(pos) % 2 == 0) ? decimals : 1 - decimals; | ||
465 | }; | ||
466 | |||
467 | /** @id MochiKit.Visual.Transitions.parabolic */ | ||
468 | MochiKit.Visual.Transitions.parabolic = function (pos) { | ||
469 | return pos * pos; | ||
470 | }; | ||
471 | |||
472 | /** @id MochiKit.Visual.Transitions.none */ | ||
473 | MochiKit.Visual.Transitions.none = function (pos) { | ||
474 | return 0; | ||
475 | }; | ||
476 | |||
477 | /** @id MochiKit.Visual.Transitions.full */ | ||
478 | MochiKit.Visual.Transitions.full = function (pos) { | ||
479 | return 1; | ||
480 | }; | ||
481 | |||
482 | /*** | ||
483 | |||
484 | Core effects | ||
485 | |||
486 | ***/ | ||
487 | |||
488 | MochiKit.Visual.ScopedQueue = function () { | ||
489 | var cls = arguments.callee; | ||
490 | if (!(this instanceof cls)) { | ||
491 | return new cls(); | ||
492 | } | ||
493 | this.__init__(); | ||
494 | }; | ||
495 | MochiKit.Visual.ScopedQueue.__export__ = false; | ||
496 | |||
497 | MochiKit.Base.update(MochiKit.Visual.ScopedQueue.prototype, { | ||
498 | __init__: function () { | ||
499 | this.effects = []; | ||
500 | this.interval = null; | ||
501 | }, | ||
502 | |||
503 | /** @id MochiKit.Visual.ScopedQueue.prototype.add */ | ||
504 | add: function (effect) { | ||
505 | var timestamp = new Date().getTime(); | ||
506 | |||
507 | var position = (typeof(effect.options.queue) == 'string') ? | ||
508 | effect.options.queue : effect.options.queue.position; | ||
509 | |||
510 | var ma = MochiKit.Base.map; | ||
511 | switch (position) { | ||
512 | case 'front': | ||
513 | // move unstarted effects after this effect | ||
514 | ma(function (e) { | ||
515 | if (e.state == 'idle') { | ||
516 | e.startOn += effect.finishOn; | ||
517 | e.finishOn += effect.finishOn; | ||
518 | } | ||
519 | }, this.effects); | ||
520 | break; | ||
521 | case 'end': | ||
522 | var finish; | ||
523 | // start effect after last queued effect has finished | ||
524 | ma(function (e) { | ||
525 | var i = e.finishOn; | ||
526 | if (i >= (finish || i)) { | ||
527 | finish = i; | ||
528 | } | ||
529 | }, this.effects); | ||
530 | timestamp = finish || timestamp; | ||
531 | break; | ||
532 | case 'break': | ||
533 | ma(function (e) { | ||
534 | e.finalize(); | ||
535 | }, this.effects); | ||
536 | break; | ||
537 | } | ||
538 | |||
539 | effect.startOn += timestamp; | ||
540 | effect.finishOn += timestamp; | ||
541 | if (!effect.options.queue.limit || | ||
542 | this.effects.length < effect.options.queue.limit) { | ||
543 | this.effects.push(effect); | ||
544 | } | ||
545 | |||
546 | if (!this.interval) { | ||
547 | this.interval = this.startLoop(MochiKit.Base.bind(this.loop, this), | ||
548 | 40); | ||
549 | } | ||
550 | }, | ||
551 | |||
552 | /** @id MochiKit.Visual.ScopedQueue.prototype.startLoop */ | ||
553 | startLoop: function (func, interval) { | ||
554 | return setInterval(func, interval); | ||
555 | }, | ||
556 | |||
557 | /** @id MochiKit.Visual.ScopedQueue.prototype.remove */ | ||
558 | remove: function (effect) { | ||
559 | this.effects = MochiKit.Base.filter(function (e) { | ||
560 | return e != effect; | ||
561 | }, this.effects); | ||
562 | if (!this.effects.length) { | ||
563 | this.stopLoop(this.interval); | ||
564 | this.interval = null; | ||
565 | } | ||
566 | }, | ||
567 | |||
568 | /** @id MochiKit.Visual.ScopedQueue.prototype.stopLoop */ | ||
569 | stopLoop: function (interval) { | ||
570 | clearInterval(interval); | ||
571 | }, | ||
572 | |||
573 | /** @id MochiKit.Visual.ScopedQueue.prototype.loop */ | ||
574 | loop: function () { | ||
575 | var timePos = new Date().getTime(); | ||
576 | MochiKit.Base.map(function (effect) { | ||
577 | effect.loop(timePos); | ||
578 | }, this.effects); | ||
579 | } | ||
580 | }); | ||
581 | |||
582 | MochiKit.Visual.Queues = { | ||
583 | __export__: false, | ||
584 | instances: {}, | ||
585 | get: function (queueName) { | ||
586 | if (typeof(queueName) != 'string') { | ||
587 | return queueName; | ||
588 | } | ||
589 | |||
590 | if (!this.instances[queueName]) { | ||
591 | this.instances[queueName] = new MochiKit.Visual.ScopedQueue(); | ||
592 | } | ||
593 | return this.instances[queueName]; | ||
594 | } | ||
595 | }; | ||
596 | |||
597 | MochiKit.Visual.Queue = MochiKit.Visual.Queues.get('global'); | ||
598 | MochiKit.Visual.Queue.__export__ = false; | ||
599 | |||
600 | MochiKit.Visual.DefaultOptions = { | ||
601 | __export__: false, | ||
602 | transition: MochiKit.Visual.Transitions.sinoidal, | ||
603 | duration: 1.0, // seconds | ||
604 | fps: 25.0, // max. 25fps due to MochiKit.Visual.Queue implementation | ||
605 | sync: false, // true for combining | ||
606 | from: 0.0, | ||
607 | to: 1.0, | ||
608 | delay: 0.0, | ||
609 | queue: 'parallel' | ||
610 | }; | ||
611 | |||
612 | MochiKit.Visual.Base = function () {}; | ||
613 | |||
614 | MochiKit.Visual.Base.prototype = { | ||
615 | /*** | ||
616 | |||
617 | Basic class for all Effects. Define a looping mechanism called for each step | ||
618 | of an effect. Don't instantiate it, only subclass it. | ||
619 | |||
620 | ***/ | ||
621 | |||
622 | __class__ : MochiKit.Visual.Base, | ||
623 | |||
624 | /** @id MochiKit.Visual.Base.prototype.start */ | ||
625 | start: function (options) { | ||
626 | var v = MochiKit.Visual; | ||
627 | this.options = MochiKit.Base.setdefault(options, | ||
628 | v.DefaultOptions); | ||
629 | this.currentFrame = 0; | ||
630 | this.state = 'idle'; | ||
631 | this.startOn = this.options.delay*1000; | ||
632 | this.finishOn = this.startOn + (this.options.duration*1000); | ||
633 | this.event('beforeStart'); | ||
634 | if (!this.options.sync) { | ||
635 | v.Queues.get(typeof(this.options.queue) == 'string' ? | ||
636 | 'global' : this.options.queue.scope).add(this); | ||
637 | } | ||
638 | }, | ||
639 | |||
640 | /** @id MochiKit.Visual.Base.prototype.loop */ | ||
641 | loop: function (timePos) { | ||
642 | if (timePos >= this.startOn) { | ||
643 | if (timePos >= this.finishOn) { | ||
644 | return this.finalize(); | ||
645 | } | ||
646 | var pos = (timePos - this.startOn) / (this.finishOn - this.startOn); | ||
647 | var frame = | ||
648 | Math.round(pos * this.options.fps * this.options.duration); | ||
649 | if (frame > this.currentFrame) { | ||
650 | this.render(pos); | ||
651 | this.currentFrame = frame; | ||
652 | } | ||
653 | } | ||
654 | }, | ||
655 | |||
656 | /** @id MochiKit.Visual.Base.prototype.render */ | ||
657 | render: function (pos) { | ||
658 | if (this.state == 'idle') { | ||
659 | this.state = 'running'; | ||
660 | this.event('beforeSetup'); | ||
661 | this.setup(); | ||
662 | this.event('afterSetup'); | ||
663 | } | ||
664 | if (this.state == 'running') { | ||
665 | if (this.options.transition) { | ||
666 | pos = this.options.transition(pos); | ||
667 | } | ||
668 | pos *= (this.options.to - this.options.from); | ||
669 | pos += this.options.from; | ||
670 | this.event('beforeUpdate'); | ||
671 | this.update(pos); | ||
672 | this.event('afterUpdate'); | ||
673 | } | ||
674 | }, | ||
675 | |||
676 | /** @id MochiKit.Visual.Base.prototype.cancel */ | ||
677 | cancel: function () { | ||
678 | if (!this.options.sync) { | ||
679 | MochiKit.Visual.Queues.get(typeof(this.options.queue) == 'string' ? | ||
680 | 'global' : this.options.queue.scope).remove(this); | ||
681 | } | ||
682 | this.state = 'finished'; | ||
683 | }, | ||
684 | |||
685 | /** @id MochiKit.Visual.Base.prototype.finalize */ | ||
686 | finalize: function () { | ||
687 | this.render(1.0); | ||
688 | this.cancel(); | ||
689 | this.event('beforeFinish'); | ||
690 | this.finish(); | ||
691 | this.event('afterFinish'); | ||
692 | }, | ||
693 | |||
694 | setup: function () { | ||
695 | }, | ||
696 | |||
697 | finish: function () { | ||
698 | }, | ||
699 | |||
700 | update: function (position) { | ||
701 | }, | ||
702 | |||
703 | /** @id MochiKit.Visual.Base.prototype.event */ | ||
704 | event: function (eventName) { | ||
705 | if (this.options[eventName + 'Internal']) { | ||
706 | this.options[eventName + 'Internal'](this); | ||
707 | } | ||
708 | if (this.options[eventName]) { | ||
709 | this.options[eventName](this); | ||
710 | } | ||
711 | }, | ||
712 | |||
713 | /** @id MochiKit.Visual.Base.prototype.repr */ | ||
714 | repr: function () { | ||
715 | return '[' + this.__class__.NAME + ', options:' + | ||
716 | MochiKit.Base.repr(this.options) + ']'; | ||
717 | } | ||
718 | }; | ||
719 | |||
720 | /** @id MochiKit.Visual.Parallel */ | ||
721 | MochiKit.Visual.Parallel = function (effects, options) { | ||
722 | var cls = arguments.callee; | ||
723 | if (!(this instanceof cls)) { | ||
724 | return new cls(effects, options); | ||
725 | } | ||
726 | |||
727 | this.__init__(effects, options); | ||
728 | }; | ||
729 | |||
730 | MochiKit.Visual.Parallel.prototype = new MochiKit.Visual.Base(); | ||
731 | |||
732 | MochiKit.Base.update(MochiKit.Visual.Parallel.prototype, { | ||
733 | /*** | ||
734 | |||
735 | Run multiple effects at the same time. | ||
736 | |||
737 | ***/ | ||
738 | |||
739 | __class__ : MochiKit.Visual.Parallel, | ||
740 | |||
741 | __init__: function (effects, options) { | ||
742 | this.effects = effects || []; | ||
743 | this.start(options); | ||
744 | }, | ||
745 | |||
746 | /** @id MochiKit.Visual.Parallel.prototype.update */ | ||
747 | update: function (position) { | ||
748 | MochiKit.Base.map(function (effect) { | ||
749 | effect.render(position); | ||
750 | }, this.effects); | ||
751 | }, | ||
752 | |||
753 | /** @id MochiKit.Visual.Parallel.prototype.finish */ | ||
754 | finish: function () { | ||
755 | MochiKit.Base.map(function (effect) { | ||
756 | effect.finalize(); | ||
757 | }, this.effects); | ||
758 | } | ||
759 | }); | ||
760 | |||
761 | /** @id MochiKit.Visual.Sequence */ | ||
762 | MochiKit.Visual.Sequence = function (effects, options) { | ||
763 | var cls = arguments.callee; | ||
764 | if (!(this instanceof cls)) { | ||
765 | return new cls(effects, options); | ||
766 | } | ||
767 | this.__init__(effects, options); | ||
768 | }; | ||
769 | |||
770 | MochiKit.Visual.Sequence.prototype = new MochiKit.Visual.Base(); | ||
771 | |||
772 | MochiKit.Base.update(MochiKit.Visual.Sequence.prototype, { | ||
773 | |||
774 | __class__ : MochiKit.Visual.Sequence, | ||
775 | |||
776 | __init__: function (effects, options) { | ||
777 | var defs = { transition: MochiKit.Visual.Transitions.linear, | ||
778 | duration: 0 }; | ||
779 | this.effects = effects || []; | ||
780 | MochiKit.Base.map(function (effect) { | ||
781 | defs.duration += effect.options.duration; | ||
782 | }, this.effects); | ||
783 | MochiKit.Base.setdefault(options, defs); | ||
784 | this.start(options); | ||
785 | }, | ||
786 | |||
787 | /** @id MochiKit.Visual.Sequence.prototype.update */ | ||
788 | update: function (position) { | ||
789 | var time = position * this.options.duration; | ||
790 | for (var i = 0; i < this.effects.length; i++) { | ||
791 | var effect = this.effects[i]; | ||
792 | if (time <= effect.options.duration) { | ||
793 | effect.render(time / effect.options.duration); | ||
794 | break; | ||
795 | } else { | ||
796 | time -= effect.options.duration; | ||
797 | } | ||
798 | } | ||
799 | }, | ||
800 | |||
801 | /** @id MochiKit.Visual.Sequence.prototype.finish */ | ||
802 | finish: function () { | ||
803 | MochiKit.Base.map(function (effect) { | ||
804 | effect.finalize(); | ||
805 | }, this.effects); | ||
806 | } | ||
807 | }); | ||
808 | |||
809 | /** @id MochiKit.Visual.Opacity */ | ||
810 | MochiKit.Visual.Opacity = function (element, options) { | ||
811 | var cls = arguments.callee; | ||
812 | if (!(this instanceof cls)) { | ||
813 | return new cls(element, options); | ||
814 | } | ||
815 | this.__init__(element, options); | ||
816 | }; | ||
817 | |||
818 | MochiKit.Visual.Opacity.prototype = new MochiKit.Visual.Base(); | ||
819 | |||
820 | MochiKit.Base.update(MochiKit.Visual.Opacity.prototype, { | ||
821 | /*** | ||
822 | |||
823 | Change the opacity of an element. | ||
824 | |||
825 | @param options: 'from' and 'to' change the starting and ending opacities. | ||
826 | Must be between 0.0 and 1.0. Default to current opacity and 1.0. | ||
827 | |||
828 | ***/ | ||
829 | |||
830 | __class__ : MochiKit.Visual.Opacity, | ||
831 | |||
832 | __init__: function (element, /* optional */options) { | ||
833 | var b = MochiKit.Base; | ||
834 | var s = MochiKit.Style; | ||
835 | this.element = MochiKit.DOM.getElement(element); | ||
836 | // make this work on IE on elements without 'layout' | ||
837 | if (this.element.currentStyle && | ||
838 | (!this.element.currentStyle.hasLayout)) { | ||
839 | s.setStyle(this.element, {zoom: 1}); | ||
840 | } | ||
841 | options = b.update({ | ||
842 | from: s.getStyle(this.element, 'opacity') || 0.0, | ||
843 | to: 1.0 | ||
844 | }, options); | ||
845 | this.start(options); | ||
846 | }, | ||
847 | |||
848 | /** @id MochiKit.Visual.Opacity.prototype.update */ | ||
849 | update: function (position) { | ||
850 | MochiKit.Style.setStyle(this.element, {'opacity': position}); | ||
851 | } | ||
852 | }); | ||
853 | |||
854 | /** @id MochiKit.Visual.Move.prototype */ | ||
855 | MochiKit.Visual.Move = function (element, options) { | ||
856 | var cls = arguments.callee; | ||
857 | if (!(this instanceof cls)) { | ||
858 | return new cls(element, options); | ||
859 | } | ||
860 | this.__init__(element, options); | ||
861 | }; | ||
862 | |||
863 | MochiKit.Visual.Move.prototype = new MochiKit.Visual.Base(); | ||
864 | |||
865 | MochiKit.Base.update(MochiKit.Visual.Move.prototype, { | ||
866 | /*** | ||
867 | |||
868 | Move an element between its current position to a defined position | ||
869 | |||
870 | @param options: 'x' and 'y' for final positions, default to 0, 0. | ||
871 | |||
872 | ***/ | ||
873 | |||
874 | __class__ : MochiKit.Visual.Move, | ||
875 | |||
876 | __init__: function (element, /* optional */options) { | ||
877 | this.element = MochiKit.DOM.getElement(element); | ||
878 | options = MochiKit.Base.update({ | ||
879 | x: 0, | ||
880 | y: 0, | ||
881 | mode: 'relative' | ||
882 | }, options); | ||
883 | this.start(options); | ||
884 | }, | ||
885 | |||
886 | /** @id MochiKit.Visual.Move.prototype.setup */ | ||
887 | setup: function () { | ||
888 | // Bug in Opera: Opera returns the 'real' position of a static element | ||
889 | // or relative element that does not have top/left explicitly set. | ||
890 | // ==> Always set top and left for position relative elements in your | ||
891 | // stylesheets (to 0 if you do not need them) | ||
892 | MochiKit.Style.makePositioned(this.element); | ||
893 | |||
894 | var s = this.element.style; | ||
895 | var originalVisibility = s.visibility; | ||
896 | var originalDisplay = s.display; | ||
897 | if (originalDisplay == 'none') { | ||
898 | s.visibility = 'hidden'; | ||
899 | s.display = ''; | ||
900 | } | ||
901 | |||
902 | this.originalLeft = parseFloat(MochiKit.Style.getStyle(this.element, 'left') || '0'); | ||
903 | this.originalTop = parseFloat(MochiKit.Style.getStyle(this.element, 'top') || '0'); | ||
904 | |||
905 | if (this.options.mode == 'absolute') { | ||
906 | // absolute movement, so we need to calc deltaX and deltaY | ||
907 | this.options.x -= this.originalLeft; | ||
908 | this.options.y -= this.originalTop; | ||
909 | } | ||
910 | if (originalDisplay == 'none') { | ||
911 | s.visibility = originalVisibility; | ||
912 | s.display = originalDisplay; | ||
913 | } | ||
914 | }, | ||
915 | |||
916 | /** @id MochiKit.Visual.Move.prototype.update */ | ||
917 | update: function (position) { | ||
918 | MochiKit.Style.setStyle(this.element, { | ||
919 | left: Math.round(this.options.x * position + this.originalLeft) + 'px', | ||
920 | top: Math.round(this.options.y * position + this.originalTop) + 'px' | ||
921 | }); | ||
922 | } | ||
923 | }); | ||
924 | |||
925 | /** @id MochiKit.Visual.Scale */ | ||
926 | MochiKit.Visual.Scale = function (element, percent, options) { | ||
927 | var cls = arguments.callee; | ||
928 | if (!(this instanceof cls)) { | ||
929 | return new cls(element, percent, options); | ||
930 | } | ||
931 | this.__init__(element, percent, options); | ||
932 | }; | ||
933 | |||
934 | MochiKit.Visual.Scale.prototype = new MochiKit.Visual.Base(); | ||
935 | |||
936 | MochiKit.Base.update(MochiKit.Visual.Scale.prototype, { | ||
937 | /*** | ||
938 | |||
939 | Change the size of an element. | ||
940 | |||
941 | @param percent: final_size = percent*original_size | ||
942 | |||
943 | @param options: several options changing scale behaviour | ||
944 | |||
945 | ***/ | ||
946 | |||
947 | __class__ : MochiKit.Visual.Scale, | ||
948 | |||
949 | __init__: function (element, percent, /* optional */options) { | ||
950 | this.element = MochiKit.DOM.getElement(element); | ||
951 | options = MochiKit.Base.update({ | ||
952 | scaleX: true, | ||
953 | scaleY: true, | ||
954 | scaleContent: true, | ||
955 | scaleFromCenter: false, | ||
956 | scaleMode: 'box', // 'box' or 'contents' or {} with provided values | ||
957 | scaleFrom: 100.0, | ||
958 | scaleTo: percent | ||
959 | }, options); | ||
960 | this.start(options); | ||
961 | }, | ||
962 | |||
963 | /** @id MochiKit.Visual.Scale.prototype.setup */ | ||
964 | setup: function () { | ||
965 | this.restoreAfterFinish = this.options.restoreAfterFinish || false; | ||
966 | this.elementPositioning = MochiKit.Style.getStyle(this.element, | ||
967 | 'position'); | ||
968 | |||
969 | var ma = MochiKit.Base.map; | ||
970 | var b = MochiKit.Base.bind; | ||
971 | this.originalStyle = {}; | ||
972 | ma(b(function (k) { | ||
973 | this.originalStyle[k] = this.element.style[k]; | ||
974 | }, this), ['top', 'left', 'width', 'height', 'fontSize']); | ||
975 | |||
976 | this.originalTop = this.element.offsetTop; | ||
977 | this.originalLeft = this.element.offsetLeft; | ||
978 | |||
979 | var fontSize = MochiKit.Style.getStyle(this.element, | ||
980 | 'font-size') || '100%'; | ||
981 | ma(b(function (fontSizeType) { | ||
982 | if (fontSize.indexOf(fontSizeType) > 0) { | ||
983 | this.fontSize = parseFloat(fontSize); | ||
984 | this.fontSizeType = fontSizeType; | ||
985 | } | ||
986 | }, this), ['em', 'px', '%']); | ||
987 | |||
988 | this.factor = (this.options.scaleTo - this.options.scaleFrom)/100; | ||
989 | |||
990 | if (/^content/.test(this.options.scaleMode)) { | ||
991 | this.dims = [this.element.scrollHeight, this.element.scrollWidth]; | ||
992 | } else if (this.options.scaleMode == 'box') { | ||
993 | this.dims = [this.element.offsetHeight, this.element.offsetWidth]; | ||
994 | } else { | ||
995 | this.dims = [this.options.scaleMode.originalHeight, | ||
996 | this.options.scaleMode.originalWidth]; | ||
997 | } | ||
998 | }, | ||
999 | |||
1000 | /** @id MochiKit.Visual.Scale.prototype.update */ | ||
1001 | update: function (position) { | ||
1002 | var currentScale = (this.options.scaleFrom/100.0) + | ||
1003 | (this.factor * position); | ||
1004 | if (this.options.scaleContent && this.fontSize) { | ||
1005 | MochiKit.Style.setStyle(this.element, { | ||
1006 | fontSize: this.fontSize * currentScale + this.fontSizeType | ||
1007 | }); | ||
1008 | } | ||
1009 | this.setDimensions(this.dims[0] * currentScale, | ||
1010 | this.dims[1] * currentScale); | ||
1011 | }, | ||
1012 | |||
1013 | /** @id MochiKit.Visual.Scale.prototype.finish */ | ||
1014 | finish: function () { | ||
1015 | if (this.restoreAfterFinish) { | ||
1016 | MochiKit.Style.setStyle(this.element, this.originalStyle); | ||
1017 | } | ||
1018 | }, | ||
1019 | |||
1020 | /** @id MochiKit.Visual.Scale.prototype.setDimensions */ | ||
1021 | setDimensions: function (height, width) { | ||
1022 | var d = {}; | ||
1023 | var r = Math.round; | ||
1024 | if (/MSIE/.test(navigator.userAgent)) { | ||
1025 | r = Math.ceil; | ||
1026 | } | ||
1027 | if (this.options.scaleX) { | ||
1028 | d.width = r(width) + 'px'; | ||
1029 | } | ||
1030 | if (this.options.scaleY) { | ||
1031 | d.height = r(height) + 'px'; | ||
1032 | } | ||
1033 | if (this.options.scaleFromCenter) { | ||
1034 | var topd = (height - this.dims[0])/2; | ||
1035 | var leftd = (width - this.dims[1])/2; | ||
1036 | if (this.elementPositioning == 'absolute') { | ||
1037 | if (this.options.scaleY) { | ||
1038 | d.top = this.originalTop - topd + 'px'; | ||
1039 | } | ||
1040 | if (this.options.scaleX) { | ||
1041 | d.left = this.originalLeft - leftd + 'px'; | ||
1042 | } | ||
1043 | } else { | ||
1044 | if (this.options.scaleY) { | ||
1045 | d.top = -topd + 'px'; | ||
1046 | } | ||
1047 | if (this.options.scaleX) { | ||
1048 | d.left = -leftd + 'px'; | ||
1049 | } | ||
1050 | } | ||
1051 | } | ||
1052 | MochiKit.Style.setStyle(this.element, d); | ||
1053 | } | ||
1054 | }); | ||
1055 | |||
1056 | /** @id MochiKit.Visual.Highlight */ | ||
1057 | MochiKit.Visual.Highlight = function (element, options) { | ||
1058 | var cls = arguments.callee; | ||
1059 | if (!(this instanceof cls)) { | ||
1060 | return new cls(element, options); | ||
1061 | } | ||
1062 | this.__init__(element, options); | ||
1063 | }; | ||
1064 | |||
1065 | MochiKit.Visual.Highlight.prototype = new MochiKit.Visual.Base(); | ||
1066 | |||
1067 | MochiKit.Base.update(MochiKit.Visual.Highlight.prototype, { | ||
1068 | /*** | ||
1069 | |||
1070 | Highlight an item of the page. | ||
1071 | |||
1072 | @param options: 'startcolor' for choosing highlighting color, default | ||
1073 | to '#ffff99'. | ||
1074 | |||
1075 | ***/ | ||
1076 | |||
1077 | __class__ : MochiKit.Visual.Highlight, | ||
1078 | |||
1079 | __init__: function (element, /* optional */options) { | ||
1080 | this.element = MochiKit.DOM.getElement(element); | ||
1081 | options = MochiKit.Base.update({ | ||
1082 | startcolor: '#ffff99' | ||
1083 | }, options); | ||
1084 | this.start(options); | ||
1085 | }, | ||
1086 | |||
1087 | /** @id MochiKit.Visual.Highlight.prototype.setup */ | ||
1088 | setup: function () { | ||
1089 | var b = MochiKit.Base; | ||
1090 | var s = MochiKit.Style; | ||
1091 | // Prevent executing on elements not in the layout flow | ||
1092 | if (s.getStyle(this.element, 'display') == 'none') { | ||
1093 | this.cancel(); | ||
1094 | return; | ||
1095 | } | ||
1096 | // Disable background image during the effect | ||
1097 | this.oldStyle = { | ||
1098 | backgroundImage: s.getStyle(this.element, 'background-image') | ||
1099 | }; | ||
1100 | s.setStyle(this.element, { | ||
1101 | backgroundImage: 'none' | ||
1102 | }); | ||
1103 | |||
1104 | if (!this.options.endcolor) { | ||
1105 | this.options.endcolor = | ||
1106 | MochiKit.Color.Color.fromBackground(this.element).toHexString(); | ||
1107 | } | ||
1108 | if (b.isUndefinedOrNull(this.options.restorecolor)) { | ||
1109 | this.options.restorecolor = s.getStyle(this.element, | ||
1110 | 'background-color'); | ||
1111 | } | ||
1112 | // init color calculations | ||
1113 | this._base = b.map(b.bind(function (i) { | ||
1114 | return parseInt( | ||
1115 | this.options.startcolor.slice(i*2 + 1, i*2 + 3), 16); | ||
1116 | }, this), [0, 1, 2]); | ||
1117 | this._delta = b.map(b.bind(function (i) { | ||
1118 | return parseInt(this.options.endcolor.slice(i*2 + 1, i*2 + 3), 16) | ||
1119 | - this._base[i]; | ||
1120 | }, this), [0, 1, 2]); | ||
1121 | }, | ||
1122 | |||
1123 | /** @id MochiKit.Visual.Highlight.prototype.update */ | ||
1124 | update: function (position) { | ||
1125 | var m = '#'; | ||
1126 | MochiKit.Base.map(MochiKit.Base.bind(function (i) { | ||
1127 | m += MochiKit.Color.toColorPart(Math.round(this._base[i] + | ||
1128 | this._delta[i]*position)); | ||
1129 | }, this), [0, 1, 2]); | ||
1130 | MochiKit.Style.setStyle(this.element, { | ||
1131 | backgroundColor: m | ||
1132 | }); | ||
1133 | }, | ||
1134 | |||
1135 | /** @id MochiKit.Visual.Highlight.prototype.finish */ | ||
1136 | finish: function () { | ||
1137 | MochiKit.Style.setStyle(this.element, | ||
1138 | MochiKit.Base.update(this.oldStyle, { | ||
1139 | backgroundColor: this.options.restorecolor | ||
1140 | })); | ||
1141 | } | ||
1142 | }); | ||
1143 | |||
1144 | /** @id MochiKit.Visual.ScrollTo */ | ||
1145 | MochiKit.Visual.ScrollTo = function (element, options) { | ||
1146 | var cls = arguments.callee; | ||
1147 | if (!(this instanceof cls)) { | ||
1148 | return new cls(element, options); | ||
1149 | } | ||
1150 | this.__init__(element, options); | ||
1151 | }; | ||
1152 | |||
1153 | MochiKit.Visual.ScrollTo.prototype = new MochiKit.Visual.Base(); | ||
1154 | |||
1155 | MochiKit.Base.update(MochiKit.Visual.ScrollTo.prototype, { | ||
1156 | /*** | ||
1157 | |||
1158 | Scroll to an element in the page. | ||
1159 | |||
1160 | ***/ | ||
1161 | |||
1162 | __class__ : MochiKit.Visual.ScrollTo, | ||
1163 | |||
1164 | __init__: function (element, /* optional */options) { | ||
1165 | this.element = MochiKit.DOM.getElement(element); | ||
1166 | this.start(options); | ||
1167 | }, | ||
1168 | |||
1169 | /** @id MochiKit.Visual.ScrollTo.prototype.setup */ | ||
1170 | setup: function () { | ||
1171 | var p = MochiKit.Position; | ||
1172 | p.prepare(); | ||
1173 | var offsets = p.cumulativeOffset(this.element); | ||
1174 | if (this.options.offset) { | ||
1175 | offsets.y += this.options.offset; | ||
1176 | } | ||
1177 | var max; | ||
1178 | if (window.innerHeight) { | ||
1179 | max = window.innerHeight - window.height; | ||
1180 | } else if (document.documentElement && | ||
1181 | document.documentElement.clientHeight) { | ||
1182 | max = document.documentElement.clientHeight - | ||
1183 | document.body.scrollHeight; | ||
1184 | } else if (document.body) { | ||
1185 | max = document.body.clientHeight - document.body.scrollHeight; | ||
1186 | } | ||
1187 | this.scrollStart = p.windowOffset.y; | ||
1188 | this.delta = (offsets.y > max ? max : offsets.y) - this.scrollStart; | ||
1189 | }, | ||
1190 | |||
1191 | /** @id MochiKit.Visual.ScrollTo.prototype.update */ | ||
1192 | update: function (position) { | ||
1193 | var p = MochiKit.Position; | ||
1194 | p.prepare(); | ||
1195 | window.scrollTo(p.windowOffset.x, this.scrollStart + (position * this.delta)); | ||
1196 | } | ||
1197 | }); | ||
1198 | |||
1199 | MochiKit.Visual._CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/; | ||
1200 | |||
1201 | MochiKit.Visual.Morph = function (element, options) { | ||
1202 | var cls = arguments.callee; | ||
1203 | if (!(this instanceof cls)) { | ||
1204 | return new cls(element, options); | ||
1205 | } | ||
1206 | this.__init__(element, options); | ||
1207 | }; | ||
1208 | |||
1209 | MochiKit.Visual.Morph.prototype = new MochiKit.Visual.Base(); | ||
1210 | |||
1211 | MochiKit.Base.update(MochiKit.Visual.Morph.prototype, { | ||
1212 | /*** | ||
1213 | |||
1214 | Morph effect: make a transformation from current style to the given style, | ||
1215 | automatically making a transition between the two. | ||
1216 | |||
1217 | ***/ | ||
1218 | |||
1219 | __class__ : MochiKit.Visual.Morph, | ||
1220 | |||
1221 | __init__: function (element, /* optional */options) { | ||
1222 | this.element = MochiKit.DOM.getElement(element); | ||
1223 | this.start(options); | ||
1224 | }, | ||
1225 | |||
1226 | /** @id MochiKit.Visual.Morph.prototype.setup */ | ||
1227 | setup: function () { | ||
1228 | var b = MochiKit.Base; | ||
1229 | var style = this.options.style; | ||
1230 | this.styleStart = {}; | ||
1231 | this.styleEnd = {}; | ||
1232 | this.units = {}; | ||
1233 | var value, unit; | ||
1234 | for (var s in style) { | ||
1235 | value = style[s]; | ||
1236 | s = b.camelize(s); | ||
1237 | if (MochiKit.Visual._CSS_LENGTH.test(value)) { | ||
1238 | var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/); | ||
1239 | value = parseFloat(components[1]); | ||
1240 | unit = (components.length == 3) ? components[2] : null; | ||
1241 | this.styleEnd[s] = value; | ||
1242 | this.units[s] = unit; | ||
1243 | value = MochiKit.Style.getStyle(this.element, s); | ||
1244 | components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/); | ||
1245 | value = parseFloat(components[1]); | ||
1246 | this.styleStart[s] = value; | ||
1247 | } else if (/[Cc]olor$/.test(s)) { | ||
1248 | var c = MochiKit.Color.Color; | ||
1249 | value = c.fromString(value); | ||
1250 | if (value) { | ||
1251 | this.units[s] = "color"; | ||
1252 | this.styleEnd[s] = value.toHexString(); | ||
1253 | value = MochiKit.Style.getStyle(this.element, s); | ||
1254 | this.styleStart[s] = c.fromString(value).toHexString(); | ||
1255 | |||
1256 | this.styleStart[s] = b.map(b.bind(function (i) { | ||
1257 | return parseInt( | ||
1258 | this.styleStart[s].slice(i*2 + 1, i*2 + 3), 16); | ||
1259 | }, this), [0, 1, 2]); | ||
1260 | this.styleEnd[s] = b.map(b.bind(function (i) { | ||
1261 | return parseInt( | ||
1262 | this.styleEnd[s].slice(i*2 + 1, i*2 + 3), 16); | ||
1263 | }, this), [0, 1, 2]); | ||
1264 | } | ||
1265 | } else { | ||
1266 | // For non-length & non-color properties, we just set the value | ||
1267 | this.element.style[s] = value; | ||
1268 | } | ||
1269 | } | ||
1270 | }, | ||
1271 | |||
1272 | /** @id MochiKit.Visual.Morph.prototype.update */ | ||
1273 | update: function (position) { | ||
1274 | var value; | ||
1275 | for (var s in this.styleStart) { | ||
1276 | if (this.units[s] == "color") { | ||
1277 | var m = '#'; | ||
1278 | var start = this.styleStart[s]; | ||
1279 | var end = this.styleEnd[s]; | ||
1280 | MochiKit.Base.map(MochiKit.Base.bind(function (i) { | ||
1281 | m += MochiKit.Color.toColorPart(Math.round(start[i] + | ||
1282 | (end[i] - start[i])*position)); | ||
1283 | }, this), [0, 1, 2]); | ||
1284 | this.element.style[s] = m; | ||
1285 | } else { | ||
1286 | value = this.styleStart[s] + Math.round((this.styleEnd[s] - this.styleStart[s]) * position * 1000) / 1000 + this.units[s]; | ||
1287 | this.element.style[s] = value; | ||
1288 | } | ||
1289 | } | ||
1290 | } | ||
1291 | }); | ||
1292 | |||
1293 | /*** | ||
1294 | |||
1295 | Combination effects. | ||
1296 | |||
1297 | ***/ | ||
1298 | |||
1299 | /** @id MochiKit.Visual.fade */ | ||
1300 | MochiKit.Visual.fade = function (element, /* optional */ options) { | ||
1301 | /*** | ||
1302 | |||
1303 | Fade a given element: change its opacity and hide it in the end. | ||
1304 | |||
1305 | @param options: 'to' and 'from' to change opacity. | ||
1306 | |||
1307 | ***/ | ||
1308 | var s = MochiKit.Style; | ||
1309 | var oldOpacity = s.getStyle(element, 'opacity'); | ||
1310 | options = MochiKit.Base.update({ | ||
1311 | from: s.getStyle(element, 'opacity') || 1.0, | ||
1312 | to: 0.0, | ||
1313 | afterFinishInternal: function (effect) { | ||
1314 | if (effect.options.to !== 0) { | ||
1315 | return; | ||
1316 | } | ||
1317 | s.hideElement(effect.element); | ||
1318 | s.setStyle(effect.element, {'opacity': oldOpacity}); | ||
1319 | } | ||
1320 | }, options); | ||
1321 | return new MochiKit.Visual.Opacity(element, options); | ||
1322 | }; | ||
1323 | |||
1324 | /** @id MochiKit.Visual.appear */ | ||
1325 | MochiKit.Visual.appear = function (element, /* optional */ options) { | ||
1326 | /*** | ||
1327 | |||
1328 | Make an element appear. | ||
1329 | |||
1330 | @param options: 'to' and 'from' to change opacity. | ||
1331 | |||
1332 | ***/ | ||
1333 | var s = MochiKit.Style; | ||
1334 | var v = MochiKit.Visual; | ||
1335 | options = MochiKit.Base.update({ | ||
1336 | from: (s.getStyle(element, 'display') == 'none' ? 0.0 : | ||
1337 | s.getStyle(element, 'opacity') || 0.0), | ||
1338 | to: 1.0, | ||
1339 | // force Safari to render floated elements properly | ||
1340 | afterFinishInternal: function (effect) { | ||
1341 | v._forceRerendering(effect.element); | ||
1342 | }, | ||
1343 | beforeSetupInternal: function (effect) { | ||
1344 | s.setStyle(effect.element, {'opacity': effect.options.from}); | ||
1345 | s.showElement(effect.element); | ||
1346 | } | ||
1347 | }, options); | ||
1348 | return new v.Opacity(element, options); | ||
1349 | }; | ||
1350 | |||
1351 | /** @id MochiKit.Visual.puff */ | ||
1352 | MochiKit.Visual.puff = function (element, /* optional */ options) { | ||
1353 | /*** | ||
1354 | |||
1355 | 'Puff' an element: grow it to double size, fading it and make it hidden. | ||
1356 | |||
1357 | ***/ | ||
1358 | var s = MochiKit.Style; | ||
1359 | var v = MochiKit.Visual; | ||
1360 | element = MochiKit.DOM.getElement(element); | ||
1361 | var elementDimensions = MochiKit.Style.getElementDimensions(element, true); | ||
1362 | var oldStyle = { | ||
1363 | position: s.getStyle(element, 'position'), | ||
1364 | top: element.style.top, | ||
1365 | left: element.style.left, | ||
1366 | width: element.style.width, | ||
1367 | height: element.style.height, | ||
1368 | opacity: s.getStyle(element, 'opacity') | ||
1369 | }; | ||
1370 | options = MochiKit.Base.update({ | ||
1371 | beforeSetupInternal: function (effect) { | ||
1372 | MochiKit.Position.absolutize(effect.effects[0].element); | ||
1373 | }, | ||
1374 | afterFinishInternal: function (effect) { | ||
1375 | s.hideElement(effect.effects[0].element); | ||
1376 | s.setStyle(effect.effects[0].element, oldStyle); | ||
1377 | }, | ||
1378 | scaleContent: true, | ||
1379 | scaleFromCenter: true | ||
1380 | }, options); | ||
1381 | return new v.Parallel( | ||
1382 | [new v.Scale(element, 200, | ||
1383 | {sync: true, scaleFromCenter: options.scaleFromCenter, | ||
1384 | scaleMode: {originalHeight: elementDimensions.h, | ||
1385 | originalWidth: elementDimensions.w}, | ||
1386 | scaleContent: options.scaleContent, restoreAfterFinish: true}), | ||
1387 | new v.Opacity(element, {sync: true, to: 0.0 })], | ||
1388 | options); | ||
1389 | }; | ||
1390 | |||
1391 | /** @id MochiKit.Visual.blindUp */ | ||
1392 | MochiKit.Visual.blindUp = function (element, /* optional */ options) { | ||
1393 | /*** | ||
1394 | |||
1395 | Blind an element up: change its vertical size to 0. | ||
1396 | |||
1397 | ***/ | ||
1398 | var d = MochiKit.DOM; | ||
1399 | var s = MochiKit.Style; | ||
1400 | element = d.getElement(element); | ||
1401 | var elementDimensions = s.getElementDimensions(element, true); | ||
1402 | var elemClip = s.makeClipping(element); | ||
1403 | options = MochiKit.Base.update({ | ||
1404 | scaleContent: false, | ||
1405 | scaleX: false, | ||
1406 | scaleMode: {originalHeight: elementDimensions.h, | ||
1407 | originalWidth: elementDimensions.w}, | ||
1408 | restoreAfterFinish: true, | ||
1409 | afterFinishInternal: function (effect) { | ||
1410 | s.hideElement(effect.element); | ||
1411 | s.undoClipping(effect.element, elemClip); | ||
1412 | } | ||
1413 | }, options); | ||
1414 | return new MochiKit.Visual.Scale(element, 0, options); | ||
1415 | }; | ||
1416 | |||
1417 | /** @id MochiKit.Visual.blindDown */ | ||
1418 | MochiKit.Visual.blindDown = function (element, /* optional */ options) { | ||
1419 | /*** | ||
1420 | |||
1421 | Blind an element down: restore its vertical size. | ||
1422 | |||
1423 | ***/ | ||
1424 | var d = MochiKit.DOM; | ||
1425 | var s = MochiKit.Style; | ||
1426 | element = d.getElement(element); | ||
1427 | var elementDimensions = s.getElementDimensions(element, true); | ||
1428 | var elemClip; | ||
1429 | options = MochiKit.Base.update({ | ||
1430 | scaleContent: false, | ||
1431 | scaleX: false, | ||
1432 | scaleFrom: 0, | ||
1433 | scaleMode: {originalHeight: elementDimensions.h, | ||
1434 | originalWidth: elementDimensions.w}, | ||
1435 | restoreAfterFinish: true, | ||
1436 | afterSetupInternal: function (effect) { | ||
1437 | elemClip = s.makeClipping(effect.element); | ||
1438 | s.setStyle(effect.element, {height: '0px'}); | ||
1439 | s.showElement(effect.element); | ||
1440 | }, | ||
1441 | afterFinishInternal: function (effect) { | ||
1442 | s.undoClipping(effect.element, elemClip); | ||
1443 | } | ||
1444 | }, options); | ||
1445 | return new MochiKit.Visual.Scale(element, 100, options); | ||
1446 | }; | ||
1447 | |||
1448 | /** @id MochiKit.Visual.switchOff */ | ||
1449 | MochiKit.Visual.switchOff = function (element, /* optional */ options) { | ||
1450 | /*** | ||
1451 | |||
1452 | Apply a switch-off-like effect. | ||
1453 | |||
1454 | ***/ | ||
1455 | var d = MochiKit.DOM; | ||
1456 | var s = MochiKit.Style; | ||
1457 | element = d.getElement(element); | ||
1458 | var elementDimensions = s.getElementDimensions(element, true); | ||
1459 | var oldOpacity = s.getStyle(element, 'opacity'); | ||
1460 | var elemClip; | ||
1461 | options = MochiKit.Base.update({ | ||
1462 | duration: 0.7, | ||
1463 | restoreAfterFinish: true, | ||
1464 | beforeSetupInternal: function (effect) { | ||
1465 | s.makePositioned(element); | ||
1466 | elemClip = s.makeClipping(element); | ||
1467 | }, | ||
1468 | afterFinishInternal: function (effect) { | ||
1469 | s.hideElement(element); | ||
1470 | s.undoClipping(element, elemClip); | ||
1471 | s.undoPositioned(element); | ||
1472 | s.setStyle(element, {'opacity': oldOpacity}); | ||
1473 | } | ||
1474 | }, options); | ||
1475 | var v = MochiKit.Visual; | ||
1476 | return new v.Sequence( | ||
1477 | [new v.appear(element, | ||
1478 | { sync: true, duration: 0.57 * options.duration, | ||
1479 | from: 0, transition: v.Transitions.flicker }), | ||
1480 | new v.Scale(element, 1, | ||
1481 | { sync: true, duration: 0.43 * options.duration, | ||
1482 | scaleFromCenter: true, scaleX: false, | ||
1483 | scaleMode: {originalHeight: elementDimensions.h, | ||
1484 | originalWidth: elementDimensions.w}, | ||
1485 | scaleContent: false, restoreAfterFinish: true })], | ||
1486 | options); | ||
1487 | }; | ||
1488 | |||
1489 | /** @id MochiKit.Visual.dropOut */ | ||
1490 | MochiKit.Visual.dropOut = function (element, /* optional */ options) { | ||
1491 | /*** | ||
1492 | |||
1493 | Make an element fall and disappear. | ||
1494 | |||
1495 | ***/ | ||
1496 | var d = MochiKit.DOM; | ||
1497 | var s = MochiKit.Style; | ||
1498 | element = d.getElement(element); | ||
1499 | var oldStyle = { | ||
1500 | top: s.getStyle(element, 'top'), | ||
1501 | left: s.getStyle(element, 'left'), | ||
1502 | opacity: s.getStyle(element, 'opacity') | ||
1503 | }; | ||
1504 | |||
1505 | options = MochiKit.Base.update({ | ||
1506 | duration: 0.5, | ||
1507 | distance: 100, | ||
1508 | beforeSetupInternal: function (effect) { | ||
1509 | s.makePositioned(effect.effects[0].element); | ||
1510 | }, | ||
1511 | afterFinishInternal: function (effect) { | ||
1512 | s.hideElement(effect.effects[0].element); | ||
1513 | s.undoPositioned(effect.effects[0].element); | ||
1514 | s.setStyle(effect.effects[0].element, oldStyle); | ||
1515 | } | ||
1516 | }, options); | ||
1517 | var v = MochiKit.Visual; | ||
1518 | return new v.Parallel( | ||
1519 | [new v.Move(element, {x: 0, y: options.distance, sync: true}), | ||
1520 | new v.Opacity(element, {sync: true, to: 0.0})], | ||
1521 | options); | ||
1522 | }; | ||
1523 | |||
1524 | /** @id MochiKit.Visual.shake */ | ||
1525 | MochiKit.Visual.shake = function (element, /* optional */ options) { | ||
1526 | /*** | ||
1527 | |||
1528 | Move an element from left to right several times. | ||
1529 | |||
1530 | ***/ | ||
1531 | var d = MochiKit.DOM; | ||
1532 | var v = MochiKit.Visual; | ||
1533 | var s = MochiKit.Style; | ||
1534 | element = d.getElement(element); | ||
1535 | var oldStyle = { | ||
1536 | top: s.getStyle(element, 'top'), | ||
1537 | left: s.getStyle(element, 'left') | ||
1538 | }; | ||
1539 | options = MochiKit.Base.update({ | ||
1540 | duration: 0.5, | ||
1541 | afterFinishInternal: function (effect) { | ||
1542 | s.undoPositioned(element); | ||
1543 | s.setStyle(element, oldStyle); | ||
1544 | } | ||
1545 | }, options); | ||
1546 | return new v.Sequence( | ||
1547 | [new v.Move(element, { sync: true, duration: 0.1 * options.duration, | ||
1548 | x: 20, y: 0 }), | ||
1549 | new v.Move(element, { sync: true, duration: 0.2 * options.duration, | ||
1550 | x: -40, y: 0 }), | ||
1551 | new v.Move(element, { sync: true, duration: 0.2 * options.duration, | ||
1552 | x: 40, y: 0 }), | ||
1553 | new v.Move(element, { sync: true, duration: 0.2 * options.duration, | ||
1554 | x: -40, y: 0 }), | ||
1555 | new v.Move(element, { sync: true, duration: 0.2 * options.duration, | ||
1556 | x: 40, y: 0 }), | ||
1557 | new v.Move(element, { sync: true, duration: 0.1 * options.duration, | ||
1558 | x: -20, y: 0 })], | ||
1559 | options); | ||
1560 | }; | ||
1561 | |||
1562 | /** @id MochiKit.Visual.slideDown */ | ||
1563 | MochiKit.Visual.slideDown = function (element, /* optional */ options) { | ||
1564 | /*** | ||
1565 | |||
1566 | Slide an element down. | ||
1567 | It needs to have the content of the element wrapped in a container | ||
1568 | element with fixed height. | ||
1569 | |||
1570 | ***/ | ||
1571 | var d = MochiKit.DOM; | ||
1572 | var b = MochiKit.Base; | ||
1573 | var s = MochiKit.Style; | ||
1574 | element = d.getElement(element); | ||
1575 | if (!element.firstChild) { | ||
1576 | throw new Error("MochiKit.Visual.slideDown must be used on a element with a child"); | ||
1577 | } | ||
1578 | d.removeEmptyTextNodes(element); | ||
1579 | var oldInnerBottom = s.getStyle(element.firstChild, 'bottom') || 0; | ||
1580 | var elementDimensions = s.getElementDimensions(element, true); | ||
1581 | var elemClip; | ||
1582 | options = b.update({ | ||
1583 | scaleContent: false, | ||
1584 | scaleX: false, | ||
1585 | scaleFrom: 0, | ||
1586 | scaleMode: {originalHeight: elementDimensions.h, | ||
1587 | originalWidth: elementDimensions.w}, | ||
1588 | restoreAfterFinish: true, | ||
1589 | afterSetupInternal: function (effect) { | ||
1590 | s.makePositioned(effect.element); | ||
1591 | s.makePositioned(effect.element.firstChild); | ||
1592 | if (/Opera/.test(navigator.userAgent)) { | ||
1593 | s.setStyle(effect.element, {top: ''}); | ||
1594 | } | ||
1595 | elemClip = s.makeClipping(effect.element); | ||
1596 | s.setStyle(effect.element, {height: '0px'}); | ||
1597 | s.showElement(effect.element); | ||
1598 | }, | ||
1599 | afterUpdateInternal: function (effect) { | ||
1600 | var elementDimensions = s.getElementDimensions(effect.element, true); | ||
1601 | s.setStyle(effect.element.firstChild, | ||
1602 | {bottom: (effect.dims[0] - elementDimensions.h) + 'px'}); | ||
1603 | }, | ||
1604 | afterFinishInternal: function (effect) { | ||
1605 | s.undoClipping(effect.element, elemClip); | ||
1606 | // IE will crash if child is undoPositioned first | ||
1607 | if (/MSIE/.test(navigator.userAgent)) { | ||
1608 | s.undoPositioned(effect.element); | ||
1609 | s.undoPositioned(effect.element.firstChild); | ||
1610 | } else { | ||
1611 | s.undoPositioned(effect.element.firstChild); | ||
1612 | s.undoPositioned(effect.element); | ||
1613 | } | ||
1614 | s.setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); | ||
1615 | } | ||
1616 | }, options); | ||
1617 | |||
1618 | return new MochiKit.Visual.Scale(element, 100, options); | ||
1619 | }; | ||
1620 | |||
1621 | /** @id MochiKit.Visual.slideUp */ | ||
1622 | MochiKit.Visual.slideUp = function (element, /* optional */ options) { | ||
1623 | /*** | ||
1624 | |||
1625 | Slide an element up. | ||
1626 | It needs to have the content of the element wrapped in a container | ||
1627 | element with fixed height. | ||
1628 | |||
1629 | ***/ | ||
1630 | var d = MochiKit.DOM; | ||
1631 | var b = MochiKit.Base; | ||
1632 | var s = MochiKit.Style; | ||
1633 | element = d.getElement(element); | ||
1634 | if (!element.firstChild) { | ||
1635 | throw new Error("MochiKit.Visual.slideUp must be used on a element with a child"); | ||
1636 | } | ||
1637 | d.removeEmptyTextNodes(element); | ||
1638 | var oldInnerBottom = s.getStyle(element.firstChild, 'bottom'); | ||
1639 | var elementDimensions = s.getElementDimensions(element, true); | ||
1640 | var elemClip; | ||
1641 | options = b.update({ | ||
1642 | scaleContent: false, | ||
1643 | scaleX: false, | ||
1644 | scaleMode: {originalHeight: elementDimensions.h, | ||
1645 | originalWidth: elementDimensions.w}, | ||
1646 | scaleFrom: 100, | ||
1647 | restoreAfterFinish: true, | ||
1648 | beforeStartInternal: function (effect) { | ||
1649 | s.makePositioned(effect.element); | ||
1650 | s.makePositioned(effect.element.firstChild); | ||
1651 | if (/Opera/.test(navigator.userAgent)) { | ||
1652 | s.setStyle(effect.element, {top: ''}); | ||
1653 | } | ||
1654 | elemClip = s.makeClipping(effect.element); | ||
1655 | s.showElement(effect.element); | ||
1656 | }, | ||
1657 | afterUpdateInternal: function (effect) { | ||
1658 | var elementDimensions = s.getElementDimensions(effect.element, true); | ||
1659 | s.setStyle(effect.element.firstChild, | ||
1660 | {bottom: (effect.dims[0] - elementDimensions.h) + 'px'}); | ||
1661 | }, | ||
1662 | afterFinishInternal: function (effect) { | ||
1663 | s.hideElement(effect.element); | ||
1664 | s.undoClipping(effect.element, elemClip); | ||
1665 | s.undoPositioned(effect.element.firstChild); | ||
1666 | s.undoPositioned(effect.element); | ||
1667 | s.setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); | ||
1668 | } | ||
1669 | }, options); | ||
1670 | return new MochiKit.Visual.Scale(element, 0, options); | ||
1671 | }; | ||
1672 | |||
1673 | // Bug in opera makes the TD containing this element expand for a instance | ||
1674 | // after finish | ||
1675 | /** @id MochiKit.Visual.squish */ | ||
1676 | MochiKit.Visual.squish = function (element, /* optional */ options) { | ||
1677 | /*** | ||
1678 | |||
1679 | Reduce an element and make it disappear. | ||
1680 | |||
1681 | ***/ | ||
1682 | var d = MochiKit.DOM; | ||
1683 | var b = MochiKit.Base; | ||
1684 | var s = MochiKit.Style; | ||
1685 | var elementDimensions = s.getElementDimensions(element, true); | ||
1686 | var elemClip; | ||
1687 | options = b.update({ | ||
1688 | restoreAfterFinish: true, | ||
1689 | scaleMode: {originalHeight: elementDimensions.w, | ||
1690 | originalWidth: elementDimensions.h}, | ||
1691 | beforeSetupInternal: function (effect) { | ||
1692 | elemClip = s.makeClipping(effect.element); | ||
1693 | }, | ||
1694 | afterFinishInternal: function (effect) { | ||
1695 | s.hideElement(effect.element); | ||
1696 | s.undoClipping(effect.element, elemClip); | ||
1697 | } | ||
1698 | }, options); | ||
1699 | |||
1700 | return new MochiKit.Visual.Scale(element, /Opera/.test(navigator.userAgent) ? 1 : 0, options); | ||
1701 | }; | ||
1702 | |||
1703 | /** @id MochiKit.Visual.grow */ | ||
1704 | MochiKit.Visual.grow = function (element, /* optional */ options) { | ||
1705 | /*** | ||
1706 | |||
1707 | Grow an element to its original size. Make it zero-sized before | ||
1708 | if necessary. | ||
1709 | |||
1710 | ***/ | ||
1711 | var d = MochiKit.DOM; | ||
1712 | var v = MochiKit.Visual; | ||
1713 | var s = MochiKit.Style; | ||
1714 | element = d.getElement(element); | ||
1715 | options = MochiKit.Base.update({ | ||
1716 | direction: 'center', | ||
1717 | moveTransition: v.Transitions.sinoidal, | ||
1718 | scaleTransition: v.Transitions.sinoidal, | ||
1719 | opacityTransition: v.Transitions.full, | ||
1720 | scaleContent: true, | ||
1721 | scaleFromCenter: false | ||
1722 | }, options); | ||
1723 | var oldStyle = { | ||
1724 | top: element.style.top, | ||
1725 | left: element.style.left, | ||
1726 | height: element.style.height, | ||
1727 | width: element.style.width, | ||
1728 | opacity: s.getStyle(element, 'opacity') | ||
1729 | }; | ||
1730 | var dims = s.getElementDimensions(element, true); | ||
1731 | var initialMoveX, initialMoveY; | ||
1732 | var moveX, moveY; | ||
1733 | |||
1734 | switch (options.direction) { | ||
1735 | case 'top-left': | ||
1736 | initialMoveX = initialMoveY = moveX = moveY = 0; | ||
1737 | break; | ||
1738 | case 'top-right': | ||
1739 | initialMoveX = dims.w; | ||
1740 | initialMoveY = moveY = 0; | ||
1741 | moveX = -dims.w; | ||
1742 | break; | ||
1743 | case 'bottom-left': | ||
1744 | initialMoveX = moveX = 0; | ||
1745 | initialMoveY = dims.h; | ||
1746 | moveY = -dims.h; | ||
1747 | break; | ||
1748 | case 'bottom-right': | ||
1749 | initialMoveX = dims.w; | ||
1750 | initialMoveY = dims.h; | ||
1751 | moveX = -dims.w; | ||
1752 | moveY = -dims.h; | ||
1753 | break; | ||
1754 | case 'center': | ||
1755 | initialMoveX = dims.w / 2; | ||
1756 | initialMoveY = dims.h / 2; | ||
1757 | moveX = -dims.w / 2; | ||
1758 | moveY = -dims.h / 2; | ||
1759 | break; | ||
1760 | } | ||
1761 | |||
1762 | var optionsParallel = MochiKit.Base.update({ | ||
1763 | beforeSetupInternal: function (effect) { | ||
1764 | s.setStyle(effect.effects[0].element, {height: '0px'}); | ||
1765 | s.showElement(effect.effects[0].element); | ||
1766 | }, | ||
1767 | afterFinishInternal: function (effect) { | ||
1768 | s.undoClipping(effect.effects[0].element); | ||
1769 | s.undoPositioned(effect.effects[0].element); | ||
1770 | s.setStyle(effect.effects[0].element, oldStyle); | ||
1771 | } | ||
1772 | }, options); | ||
1773 | |||
1774 | return new v.Move(element, { | ||
1775 | x: initialMoveX, | ||
1776 | y: initialMoveY, | ||
1777 | duration: 0.01, | ||
1778 | beforeSetupInternal: function (effect) { | ||
1779 | s.hideElement(effect.element); | ||
1780 | s.makeClipping(effect.element); | ||
1781 | s.makePositioned(effect.element); | ||
1782 | }, | ||
1783 | afterFinishInternal: function (effect) { | ||
1784 | new v.Parallel( | ||
1785 | [new v.Opacity(effect.element, { | ||
1786 | sync: true, to: 1.0, from: 0.0, | ||
1787 | transition: options.opacityTransition | ||
1788 | }), | ||
1789 | new v.Move(effect.element, { | ||
1790 | x: moveX, y: moveY, sync: true, | ||
1791 | transition: options.moveTransition | ||
1792 | }), | ||
1793 | new v.Scale(effect.element, 100, { | ||
1794 | scaleMode: {originalHeight: dims.h, | ||
1795 | originalWidth: dims.w}, | ||
1796 | sync: true, | ||
1797 | scaleFrom: /Opera/.test(navigator.userAgent) ? 1 : 0, | ||
1798 | transition: options.scaleTransition, | ||
1799 | scaleContent: options.scaleContent, | ||
1800 | scaleFromCenter: options.scaleFromCenter, | ||
1801 | restoreAfterFinish: true | ||
1802 | }) | ||
1803 | ], optionsParallel | ||
1804 | ); | ||
1805 | } | ||
1806 | }); | ||
1807 | }; | ||
1808 | |||
1809 | /** @id MochiKit.Visual.shrink */ | ||
1810 | MochiKit.Visual.shrink = function (element, /* optional */ options) { | ||
1811 | /*** | ||
1812 | |||
1813 | Shrink an element and make it disappear. | ||
1814 | |||
1815 | ***/ | ||
1816 | var d = MochiKit.DOM; | ||
1817 | var v = MochiKit.Visual; | ||
1818 | var s = MochiKit.Style; | ||
1819 | element = d.getElement(element); | ||
1820 | options = MochiKit.Base.update({ | ||
1821 | direction: 'center', | ||
1822 | moveTransition: v.Transitions.sinoidal, | ||
1823 | scaleTransition: v.Transitions.sinoidal, | ||
1824 | opacityTransition: v.Transitions.none, | ||
1825 | scaleContent: true, | ||
1826 | scaleFromCenter: false | ||
1827 | }, options); | ||
1828 | var oldStyle = { | ||
1829 | top: element.style.top, | ||
1830 | left: element.style.left, | ||
1831 | height: element.style.height, | ||
1832 | width: element.style.width, | ||
1833 | opacity: s.getStyle(element, 'opacity') | ||
1834 | }; | ||
1835 | |||
1836 | var dims = s.getElementDimensions(element, true); | ||
1837 | var moveX, moveY; | ||
1838 | |||
1839 | switch (options.direction) { | ||
1840 | case 'top-left': | ||
1841 | moveX = moveY = 0; | ||
1842 | break; | ||
1843 | case 'top-right': | ||
1844 | moveX = dims.w; | ||
1845 | moveY = 0; | ||
1846 | break; | ||
1847 | case 'bottom-left': | ||
1848 | moveX = 0; | ||
1849 | moveY = dims.h; | ||
1850 | break; | ||
1851 | case 'bottom-right': | ||
1852 | moveX = dims.w; | ||
1853 | moveY = dims.h; | ||
1854 | break; | ||
1855 | case 'center': | ||
1856 | moveX = dims.w / 2; | ||
1857 | moveY = dims.h / 2; | ||
1858 | break; | ||
1859 | } | ||
1860 | var elemClip; | ||
1861 | |||
1862 | var optionsParallel = MochiKit.Base.update({ | ||
1863 | beforeStartInternal: function (effect) { | ||
1864 | s.makePositioned(effect.effects[0].element); | ||
1865 | elemClip = s.makeClipping(effect.effects[0].element); | ||
1866 | }, | ||
1867 | afterFinishInternal: function (effect) { | ||
1868 | s.hideElement(effect.effects[0].element); | ||
1869 | s.undoClipping(effect.effects[0].element, elemClip); | ||
1870 | s.undoPositioned(effect.effects[0].element); | ||
1871 | s.setStyle(effect.effects[0].element, oldStyle); | ||
1872 | } | ||
1873 | }, options); | ||
1874 | |||
1875 | return new v.Parallel( | ||
1876 | [new v.Opacity(element, { | ||
1877 | sync: true, to: 0.0, from: 1.0, | ||
1878 | transition: options.opacityTransition | ||
1879 | }), | ||
1880 | new v.Scale(element, /Opera/.test(navigator.userAgent) ? 1 : 0, { | ||
1881 | scaleMode: {originalHeight: dims.h, originalWidth: dims.w}, | ||
1882 | sync: true, transition: options.scaleTransition, | ||
1883 | scaleContent: options.scaleContent, | ||
1884 | scaleFromCenter: options.scaleFromCenter, | ||
1885 | restoreAfterFinish: true | ||
1886 | }), | ||
1887 | new v.Move(element, { | ||
1888 | x: moveX, y: moveY, sync: true, transition: options.moveTransition | ||
1889 | }) | ||
1890 | ], optionsParallel | ||
1891 | ); | ||
1892 | }; | ||
1893 | |||
1894 | /** @id MochiKit.Visual.pulsate */ | ||
1895 | MochiKit.Visual.pulsate = function (element, /* optional */ options) { | ||
1896 | /*** | ||
1897 | |||
1898 | Pulse an element between appear/fade. | ||
1899 | |||
1900 | ***/ | ||
1901 | var d = MochiKit.DOM; | ||
1902 | var v = MochiKit.Visual; | ||
1903 | var b = MochiKit.Base; | ||
1904 | var oldOpacity = MochiKit.Style.getStyle(element, 'opacity'); | ||
1905 | options = b.update({ | ||
1906 | duration: 3.0, | ||
1907 | from: 0, | ||
1908 | afterFinishInternal: function (effect) { | ||
1909 | MochiKit.Style.setStyle(effect.element, {'opacity': oldOpacity}); | ||
1910 | } | ||
1911 | }, options); | ||
1912 | var transition = options.transition || v.Transitions.sinoidal; | ||
1913 | options.transition = function (pos) { | ||
1914 | return transition(1 - v.Transitions.pulse(pos, options.pulses)); | ||
1915 | }; | ||
1916 | return new v.Opacity(element, options); | ||
1917 | }; | ||
1918 | |||
1919 | /** @id MochiKit.Visual.fold */ | ||
1920 | MochiKit.Visual.fold = function (element, /* optional */ options) { | ||
1921 | /*** | ||
1922 | |||
1923 | Fold an element, first vertically, then horizontally. | ||
1924 | |||
1925 | ***/ | ||
1926 | var d = MochiKit.DOM; | ||
1927 | var v = MochiKit.Visual; | ||
1928 | var s = MochiKit.Style; | ||
1929 | element = d.getElement(element); | ||
1930 | var elementDimensions = s.getElementDimensions(element, true); | ||
1931 | var oldStyle = { | ||
1932 | top: element.style.top, | ||
1933 | left: element.style.left, | ||
1934 | width: element.style.width, | ||
1935 | height: element.style.height | ||
1936 | }; | ||
1937 | var elemClip = s.makeClipping(element); | ||
1938 | options = MochiKit.Base.update({ | ||
1939 | scaleContent: false, | ||
1940 | scaleX: false, | ||
1941 | scaleMode: {originalHeight: elementDimensions.h, | ||
1942 | originalWidth: elementDimensions.w}, | ||
1943 | afterFinishInternal: function (effect) { | ||
1944 | new v.Scale(element, 1, { | ||
1945 | scaleContent: false, | ||
1946 | scaleY: false, | ||
1947 | scaleMode: {originalHeight: elementDimensions.h, | ||
1948 | originalWidth: elementDimensions.w}, | ||
1949 | afterFinishInternal: function (effect) { | ||
1950 | s.hideElement(effect.element); | ||
1951 | s.undoClipping(effect.element, elemClip); | ||
1952 | s.setStyle(effect.element, oldStyle); | ||
1953 | } | ||
1954 | }); | ||
1955 | } | ||
1956 | }, options); | ||
1957 | return new v.Scale(element, 5, options); | ||
1958 | }; | ||
1959 | |||
1960 | |||
1961 | /* end of Rico adaptation */ | ||
1962 | |||
1963 | MochiKit.Visual.__new__ = function () { | ||
1964 | var m = MochiKit.Base; | ||
1965 | |||
1966 | // Backwards compatibility aliases | ||
1967 | m._deprecated(this, 'Color', 'MochiKit.Color.Color', '1.1'); | ||
1968 | m._deprecated(this, 'getElementsComputedStyle', 'MochiKit.Style.getStyle', '1.1'); | ||
1969 | |||
1970 | m.nameFunctions(this); | ||
1971 | }; | ||
1972 | |||
1973 | MochiKit.Visual.__new__(); | ||
1974 | |||
1975 | MochiKit.Base._exportSymbols(this, MochiKit.Visual); | ||