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