nitro 0.19.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/CHANGELOG +187 -0
  2. data/INSTALL +5 -0
  3. data/README +11 -5
  4. data/doc/AUTHORS +11 -1
  5. data/doc/RELEASES +217 -0
  6. data/doc/tutorial.txt +1 -2
  7. data/lib/nitro.rb +9 -6
  8. data/lib/nitro/adapter/webrick.rb +13 -2
  9. data/lib/nitro/builder/form.rb +11 -9
  10. data/lib/nitro/builder/rss.rb +2 -2
  11. data/lib/nitro/builder/xhtml.rb +15 -0
  12. data/lib/nitro/caching.rb +15 -10
  13. data/lib/nitro/conf.rb +0 -5
  14. data/lib/nitro/controller.rb +118 -81
  15. data/lib/nitro/cookie.rb +6 -6
  16. data/lib/nitro/dispatcher.rb +62 -18
  17. data/lib/nitro/element.rb +4 -1
  18. data/lib/nitro/element/java_script.rb +15 -0
  19. data/lib/nitro/localization.rb +3 -4
  20. data/lib/nitro/markup.rb +4 -4
  21. data/lib/nitro/mixin/debug.rb +30 -0
  22. data/lib/nitro/mixin/helper.rb +14 -0
  23. data/lib/nitro/mixin/javascript.rb +137 -0
  24. data/lib/nitro/{ui → mixin}/pager.rb +110 -82
  25. data/lib/nitro/render.rb +20 -8
  26. data/lib/nitro/request.rb +6 -0
  27. data/lib/nitro/routing.rb +6 -5
  28. data/lib/nitro/runner.rb +21 -9
  29. data/lib/nitro/server.rb +95 -0
  30. data/lib/nitro/service.rb +0 -1
  31. data/lib/nitro/session.rb +4 -5
  32. data/lib/nitro/shaders.rb +2 -2
  33. data/lib/nitro/template.rb +1 -1
  34. data/lib/nitro/testing/assertions.rb +2 -4
  35. data/lib/nitro/testing/context.rb +4 -6
  36. data/proto/public/js/behaviour.js +254 -0
  37. data/proto/public/js/controls.js +446 -0
  38. data/proto/public/js/dragdrop.js +537 -0
  39. data/proto/public/js/effects.js +612 -0
  40. data/proto/public/js/prototype.js +644 -370
  41. data/proto/public/settings.xhtml +64 -0
  42. data/test/nitro/adapter/tc_cgi.rb +2 -2
  43. data/test/nitro/builder/tc_rss.rb +1 -1
  44. data/test/nitro/mixin/tc_pager.rb +35 -0
  45. data/test/nitro/tc_controller.rb +1 -1
  46. data/test/nitro/tc_cookie.rb +14 -0
  47. data/test/nitro/tc_dispatcher.rb +11 -6
  48. data/test/nitro/tc_server.rb +35 -0
  49. metadata +20 -15
  50. data/lib/nitro/builder/atom.rb +0 -74
  51. data/lib/nitro/part.rb +0 -22
  52. data/lib/nitro/simple.rb +0 -11
  53. data/lib/nitro/ui/popup.rb +0 -41
  54. data/lib/nitro/ui/tabs.rb +0 -25
  55. data/lib/nitro/uri.rb +0 -193
  56. data/test/nitro/builder/tc_atom.rb +0 -24
  57. data/test/nitro/tc_uri.rb +0 -97
  58. data/test/nitro/ui/tc_pager.rb +0 -49
@@ -0,0 +1,612 @@
1
+ // Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2
+ //
3
+ // Parts (c) 2005 Justin Palmer (http://encytemedia.com/)
4
+ // Parts (c) 2005 Mark Pilgrim (http://diveintomark.org/)
5
+ //
6
+ // Permission is hereby granted, free of charge, to any person obtaining
7
+ // a copy of this software and associated documentation files (the
8
+ // "Software"), to deal in the Software without restriction, including
9
+ // without limitation the rights to use, copy, modify, merge, publish,
10
+ // distribute, sublicense, and/or sell copies of the Software, and to
11
+ // permit persons to whom the Software is furnished to do so, subject to
12
+ // the following conditions:
13
+ //
14
+ // The above copyright notice and this permission notice shall be
15
+ // included in all copies or substantial portions of the Software.
16
+ //
17
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+
25
+
26
+ Effect = {}
27
+ Effect2 = Effect; // deprecated
28
+
29
+ /* ------------- transitions ------------- */
30
+
31
+ Effect.Transitions = {}
32
+
33
+ Effect.Transitions.linear = function(pos) {
34
+ return pos;
35
+ }
36
+ Effect.Transitions.sinoidal = function(pos) {
37
+ return (-Math.cos(pos*Math.PI)/2) + 0.5;
38
+ }
39
+ Effect.Transitions.reverse = function(pos) {
40
+ return 1-pos;
41
+ }
42
+ Effect.Transitions.flicker = function(pos) {
43
+ return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random(0.25);
44
+ }
45
+ Effect.Transitions.wobble = function(pos) {
46
+ return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
47
+ }
48
+ Effect.Transitions.pulse = function(pos) {
49
+ return (Math.floor(pos*10) % 2 == 0 ?
50
+ (pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10)));
51
+ }
52
+ Effect.Transitions.none = function(pos) {
53
+ return 0;
54
+ }
55
+ Effect.Transitions.full = function(pos) {
56
+ return 1;
57
+ }
58
+
59
+ /* ------------- element ext -------------- */
60
+
61
+ Element.makePositioned = function(element) {
62
+ element = $(element);
63
+ if(element.style.position == "")
64
+ element.style.position = "relative";
65
+ }
66
+
67
+ Element.makeClipping = function(element) {
68
+ element = $(element);
69
+ element._overflow = element.style.overflow || 'visible';
70
+ if(element._overflow!='hidden') element.style.overflow = 'hidden';
71
+ }
72
+
73
+ Element.undoClipping = function(element) {
74
+ element = $(element);
75
+ if(element._overflow!='hidden') element.style.overflow = element._overflow;
76
+ }
77
+
78
+ /* ------------- core effects ------------- */
79
+
80
+ Effect.Base = function() {};
81
+ Effect.Base.prototype = {
82
+ setOptions: function(options) {
83
+ this.options = Object.extend({
84
+ transition: Effect.Transitions.sinoidal,
85
+ duration: 1.0, // seconds
86
+ fps: 25.0, // max. 100fps
87
+ sync: false, // true for combining
88
+ from: 0.0,
89
+ to: 1.0
90
+ }, options || {});
91
+ },
92
+ start: function(options) {
93
+ this.setOptions(options || {});
94
+ this.currentFrame = 0;
95
+ this.startOn = new Date().getTime();
96
+ this.finishOn = this.startOn + (this.options.duration*1000);
97
+ if(this.options.beforeStart) this.options.beforeStart(this);
98
+ if(!this.options.sync) this.loop();
99
+ },
100
+ loop: function() {
101
+ var timePos = new Date().getTime();
102
+ if(timePos >= this.finishOn) {
103
+ this.render(this.options.to);
104
+ if(this.finish) this.finish();
105
+ if(this.options.afterFinish) this.options.afterFinish(this);
106
+ return;
107
+ }
108
+ var pos = (timePos - this.startOn) / (this.finishOn - this.startOn);
109
+ var frame = Math.round(pos * this.options.fps * this.options.duration);
110
+ if(frame > this.currentFrame) {
111
+ this.render(pos);
112
+ this.currentFrame = frame;
113
+ }
114
+ this.timeout = setTimeout(this.loop.bind(this), 10);
115
+ },
116
+ render: function(pos) {
117
+ if(this.options.transition) pos = this.options.transition(pos);
118
+ pos *= (this.options.to-this.options.from);
119
+ pos += this.options.from;
120
+ if(this.options.beforeUpdate) this.options.beforeUpdate(this);
121
+ if(this.update) this.update(pos);
122
+ if(this.options.afterUpdate) this.options.afterUpdate(this);
123
+ },
124
+ cancel: function() {
125
+ if(this.timeout) clearTimeout(this.timeout);
126
+ }
127
+ }
128
+
129
+ Effect.Parallel = Class.create();
130
+ Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
131
+ initialize: function(effects) {
132
+ this.effects = effects || [];
133
+ this.start(arguments[1]);
134
+ },
135
+ update: function(position) {
136
+ for (var i = 0; i < this.effects.length; i++)
137
+ this.effects[i].render(position);
138
+ },
139
+ finish: function(position) {
140
+ for (var i = 0; i < this.effects.length; i++)
141
+ if(this.effects[i].finish) this.effects[i].finish(position);
142
+ }
143
+ });
144
+
145
+ // Internet Explorer caveat: works only on elements the have
146
+ // a 'layout', meaning having a given width or height.
147
+ // There is no way to safely set this automatically.
148
+ Effect.Opacity = Class.create();
149
+ Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
150
+ initialize: function(element) {
151
+ this.element = $(element);
152
+ options = Object.extend({
153
+ from: 0.0,
154
+ to: 1.0
155
+ }, arguments[1] || {});
156
+ this.start(options);
157
+ },
158
+ update: function(position) {
159
+ this.setOpacity(position);
160
+ },
161
+ setOpacity: function(opacity) {
162
+ opacity = (opacity == 1) ? 0.99999 : opacity;
163
+ this.element.style.opacity = opacity;
164
+ this.element.style.filter = "alpha(opacity:"+opacity*100+")";
165
+ }
166
+ });
167
+
168
+ Effect.MoveBy = Class.create();
169
+ Object.extend(Object.extend(Effect.MoveBy.prototype, Effect.Base.prototype), {
170
+ initialize: function(element, toTop, toLeft) {
171
+ this.element = $(element);
172
+ this.originalTop = parseFloat(this.element.style.top || '0');
173
+ this.originalLeft = parseFloat(this.element.style.left || '0');
174
+ this.toTop = toTop;
175
+ this.toLeft = toLeft;
176
+ Element.makePositioned(this.element);
177
+ this.start(arguments[3]);
178
+ },
179
+ update: function(position) {
180
+ topd = this.toTop * position + this.originalTop;
181
+ leftd = this.toLeft * position + this.originalLeft;
182
+ this.setPosition(topd, leftd);
183
+ },
184
+ setPosition: function(topd, leftd) {
185
+ this.element.style.top = topd + "px";
186
+ this.element.style.left = leftd + "px";
187
+ }
188
+ });
189
+
190
+ Effect.Scale = Class.create();
191
+ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
192
+ initialize: function(element, percent) {
193
+ this.element = $(element)
194
+ options = Object.extend({
195
+ scaleX: true,
196
+ scaleY: true,
197
+ scaleContent: true,
198
+ scaleFromCenter: false,
199
+ scaleMode: 'box', // 'box' or 'contents' or {} with provided values
200
+ scaleFrom: 100.0
201
+ }, arguments[2] || {});
202
+ this.originalTop = this.element.offsetTop;
203
+ this.originalLeft = this.element.offsetLeft;
204
+ if(this.element.style.fontSize=="") this.sizeEm = 1.0;
205
+ if(this.element.style.fontSize && this.element.style.fontSize.indexOf("em")>0)
206
+ this.sizeEm = parseFloat(this.element.style.fontSize);
207
+ this.factor = (percent/100.0) - (options.scaleFrom/100.0);
208
+ if(options.scaleMode=='box') {
209
+ this.originalHeight = this.element.clientHeight;
210
+ this.originalWidth = this.element.clientWidth;
211
+ } else
212
+ if(options.scaleMode=='contents') {
213
+ this.originalHeight = this.element.scrollHeight;
214
+ this.originalWidth = this.element.scrollWidth;
215
+ } else {
216
+ this.originalHeight = options.scaleMode.originalHeight;
217
+ this.originalWidth = options.scaleMode.originalWidth;
218
+ }
219
+ this.start(options);
220
+ },
221
+
222
+ update: function(position) {
223
+ currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
224
+ if(this.options.scaleContent && this.sizeEm)
225
+ this.element.style.fontSize = this.sizeEm*currentScale + "em";
226
+ this.setDimensions(
227
+ this.originalWidth * currentScale,
228
+ this.originalHeight * currentScale);
229
+ },
230
+
231
+ setDimensions: function(width, height) {
232
+ if(this.options.scaleX) this.element.style.width = width + 'px';
233
+ if(this.options.scaleY) this.element.style.height = height + 'px';
234
+ if(this.options.scaleFromCenter) {
235
+ topd = (height - this.originalHeight)/2;
236
+ leftd = (width - this.originalWidth)/2;
237
+ if(this.element.style.position=='absolute') {
238
+ if(this.options.scaleY) this.element.style.top = this.originalTop-topd + "px";
239
+ if(this.options.scaleX) this.element.style.left = this.originalLeft-leftd + "px";
240
+ } else {
241
+ if(this.options.scaleY) this.element.style.top = -topd + "px";
242
+ if(this.options.scaleX) this.element.style.left = -leftd + "px";
243
+ }
244
+ }
245
+ }
246
+ });
247
+
248
+ Effect.Highlight = Class.create();
249
+ Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
250
+ initialize: function(element) {
251
+ this.element = $(element);
252
+
253
+ // try to parse current background color as default for endcolor
254
+ // browser stores this as: "rgb(255, 255, 255)", convert to "#ffffff" format
255
+ var endcolor = "#ffffff";
256
+ var current = this.element.style.backgroundColor;
257
+ if(current && current.slice(0,4) == "rgb(") {
258
+ endcolor = "#";
259
+ var cols = current.slice(4,current.length-1).split(',');
260
+ var i=0; do { endcolor += parseInt(cols[i]).toColorPart() } while (++i<3); }
261
+
262
+ var options = Object.extend({
263
+ startcolor: "#ffff99",
264
+ endcolor: endcolor,
265
+ restorecolor: current
266
+ }, arguments[1] || {});
267
+
268
+ // init color calculations
269
+ this.colors_base = [
270
+ parseInt(options.startcolor.slice(1,3),16),
271
+ parseInt(options.startcolor.slice(3,5),16),
272
+ parseInt(options.startcolor.slice(5),16) ];
273
+ this.colors_delta = [
274
+ parseInt(options.endcolor.slice(1,3),16)-this.colors_base[0],
275
+ parseInt(options.endcolor.slice(3,5),16)-this.colors_base[1],
276
+ parseInt(options.endcolor.slice(5),16)-this.colors_base[2] ];
277
+
278
+ this.start(options);
279
+ },
280
+ update: function(position) {
281
+ var colors = [
282
+ Math.round(this.colors_base[0]+(this.colors_delta[0]*position)),
283
+ Math.round(this.colors_base[1]+(this.colors_delta[1]*position)),
284
+ Math.round(this.colors_base[2]+(this.colors_delta[2]*position)) ];
285
+ this.element.style.backgroundColor = "#" +
286
+ colors[0].toColorPart() + colors[1].toColorPart() + colors[2].toColorPart();
287
+ },
288
+ finish: function() {
289
+ this.element.style.backgroundColor = this.options.restorecolor;
290
+ }
291
+ });
292
+
293
+ Effect.ScrollTo = Class.create();
294
+ Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
295
+ initialize: function(element) {
296
+ this.element = $(element);
297
+ Position.prepare();
298
+ var offsets = Position.cumulativeOffset(this.element);
299
+ var max = window.innerHeight ?
300
+ window.height - window.innerHeight :
301
+ document.body.scrollHeight -
302
+ (document.documentElement.clientHeight ?
303
+ document.documentElement.clientHeight : document.body.clientHeight);
304
+ this.scrollStart = Position.deltaY;
305
+ this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
306
+ this.start(arguments[1] || {});
307
+ },
308
+ update: function(position) {
309
+ Position.prepare();
310
+ window.scrollTo(Position.deltaX,
311
+ this.scrollStart + (position*this.delta));
312
+ }
313
+ });
314
+
315
+ /* ------------- prepackaged effects ------------- */
316
+
317
+ Effect.Fade = function(element) {
318
+ options = Object.extend({
319
+ from: 1.0,
320
+ to: 0.0,
321
+ afterFinish: function(effect)
322
+ { Element.hide(effect.element);
323
+ effect.setOpacity(1); }
324
+ }, arguments[1] || {});
325
+ new Effect.Opacity(element,options);
326
+ }
327
+
328
+ Effect.Appear = function(element) {
329
+ options = Object.extend({
330
+ from: 0.0,
331
+ to: 1.0,
332
+ beforeStart: function(effect)
333
+ { effect.setOpacity(0);
334
+ Element.show(effect.element); },
335
+ afterUpdate: function(effect)
336
+ { Element.show(effect.element); }
337
+ }, arguments[1] || {});
338
+ new Effect.Opacity(element,options);
339
+ }
340
+
341
+ Effect.Puff = function(element) {
342
+ new Effect.Parallel(
343
+ [ new Effect.Scale(element, 200, { sync: true, scaleFromCenter: true }),
344
+ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0 } ) ],
345
+ { duration: 1.0,
346
+ afterUpdate: function(effect)
347
+ { effect.effects[0].element.style.position = 'absolute'; },
348
+ afterFinish: function(effect)
349
+ { Element.hide(effect.effects[0].element); }
350
+ }
351
+ );
352
+ }
353
+
354
+ Effect.BlindUp = function(element) {
355
+ Element.makeClipping(element);
356
+ new Effect.Scale(element, 0,
357
+ Object.extend({ scaleContent: false,
358
+ scaleX: false,
359
+ afterFinish: function(effect)
360
+ {
361
+ Element.hide(effect.element);
362
+ Element.undoClipping(effect.element);
363
+ }
364
+ }, arguments[1] || {})
365
+ );
366
+ }
367
+
368
+ Effect.BlindDown = function(element) {
369
+ $(element).style.height = '0px';
370
+ Element.makeClipping(element);
371
+ Element.show(element);
372
+ new Effect.Scale(element, 100,
373
+ Object.extend({ scaleContent: false,
374
+ scaleX: false,
375
+ scaleMode: 'contents',
376
+ scaleFrom: 0,
377
+ afterFinish: function(effect) {
378
+ Element.undoClipping(effect.element);
379
+ }
380
+ }, arguments[1] || {})
381
+ );
382
+ }
383
+
384
+ Effect.SwitchOff = function(element) {
385
+ new Effect.Appear(element,
386
+ { duration: 0.4,
387
+ transition: Effect.Transitions.flicker,
388
+ afterFinish: function(effect)
389
+ { effect.element.style.overflow = 'hidden';
390
+ new Effect.Scale(effect.element, 1,
391
+ { duration: 0.3, scaleFromCenter: true,
392
+ scaleX: false, scaleContent: false,
393
+ afterUpdate: function(effect) {
394
+ if(effect.element.style.position=="")
395
+ effect.element.style.position = 'relative'; },
396
+ afterFinish: function(effect) { Element.hide(effect.element); }
397
+ } )
398
+ }
399
+ } );
400
+ }
401
+
402
+ Effect.DropOut = function(element) {
403
+ new Effect.Parallel(
404
+ [ new Effect.MoveBy(element, 100, 0, { sync: true }),
405
+ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0 } ) ],
406
+ { duration: 0.5,
407
+ afterFinish: function(effect)
408
+ { Element.hide(effect.effects[0].element); }
409
+ });
410
+ }
411
+
412
+ Effect.Shake = function(element) {
413
+ new Effect.MoveBy(element, 0, 20,
414
+ { duration: 0.05, afterFinish: function(effect) {
415
+ new Effect.MoveBy(effect.element, 0, -40,
416
+ { duration: 0.1, afterFinish: function(effect) {
417
+ new Effect.MoveBy(effect.element, 0, 40,
418
+ { duration: 0.1, afterFinish: function(effect) {
419
+ new Effect.MoveBy(effect.element, 0, -40,
420
+ { duration: 0.1, afterFinish: function(effect) {
421
+ new Effect.MoveBy(effect.element, 0, 40,
422
+ { duration: 0.1, afterFinish: function(effect) {
423
+ new Effect.MoveBy(effect.element, 0, -20,
424
+ { duration: 0.05, afterFinish: function(effect) {
425
+ }}) }}) }}) }}) }}) }});
426
+ }
427
+
428
+ Effect.SlideDown = function(element) {
429
+ element = $(element);
430
+ element.style.height = '0px';
431
+ Element.makeClipping(element);
432
+ Element.cleanWhitespace(element);
433
+ Element.makePositioned(element.firstChild);
434
+ Element.show(element);
435
+ new Effect.Scale(element, 100,
436
+ Object.extend({ scaleContent: false,
437
+ scaleX: false,
438
+ scaleMode: 'contents',
439
+ scaleFrom: 0,
440
+ afterUpdate: function(effect)
441
+ { effect.element.firstChild.style.bottom =
442
+ (effect.originalHeight - effect.element.clientHeight) + 'px'; },
443
+ afterFinish: function(effect)
444
+ { Element.undoClipping(effect.element); }
445
+ }, arguments[1] || {})
446
+ );
447
+ }
448
+
449
+ Effect.SlideUp = function(element) {
450
+ element = $(element);
451
+ Element.makeClipping(element);
452
+ Element.cleanWhitespace(element);
453
+ Element.makePositioned(element.firstChild);
454
+ Element.show(element);
455
+ new Effect.Scale(element, 0,
456
+ Object.extend({ scaleContent: false,
457
+ scaleX: false,
458
+ afterUpdate: function(effect)
459
+ { effect.element.firstChild.style.bottom =
460
+ (effect.originalHeight - effect.element.clientHeight) + 'px'; },
461
+ afterFinish: function(effect)
462
+ {
463
+ Element.hide(effect.element);
464
+ Element.undoClipping(effect.element);
465
+ }
466
+ }, arguments[1] || {})
467
+ );
468
+ }
469
+
470
+ Effect.Squish = function(element) {
471
+ new Effect.Scale(element, 0,
472
+ { afterFinish: function(effect) { Element.hide(effect.element); } });
473
+ }
474
+
475
+ Effect.Grow = function(element) {
476
+ element = $(element);
477
+ var options = arguments[1] || {};
478
+
479
+ var originalWidth = element.clientWidth;
480
+ var originalHeight = element.clientHeight;
481
+ element.style.overflow = 'hidden';
482
+ Element.show(element);
483
+
484
+ var direction = options.direction || 'center';
485
+ var moveTransition = options.moveTransition || Effect.Transitions.sinoidal;
486
+ var scaleTransition = options.scaleTransition || Effect.Transitions.sinoidal;
487
+ var opacityTransition = options.opacityTransition || Effect.Transitions.full;
488
+
489
+ var initialMoveX, initialMoveY;
490
+ var moveX, moveY;
491
+
492
+ switch (direction) {
493
+ case 'top-left':
494
+ initialMoveX = initialMoveY = moveX = moveY = 0;
495
+ break;
496
+ case 'top-right':
497
+ initialMoveX = originalWidth;
498
+ initialMoveY = moveY = 0;
499
+ moveX = -originalWidth;
500
+ break;
501
+ case 'bottom-left':
502
+ initialMoveX = moveX = 0;
503
+ initialMoveY = originalHeight;
504
+ moveY = -originalHeight;
505
+ break;
506
+ case 'bottom-right':
507
+ initialMoveX = originalWidth;
508
+ initialMoveY = originalHeight;
509
+ moveX = -originalWidth;
510
+ moveY = -originalHeight;
511
+ break;
512
+ case 'center':
513
+ initialMoveX = originalWidth / 2;
514
+ initialMoveY = originalHeight / 2;
515
+ moveX = -originalWidth / 2;
516
+ moveY = -originalHeight / 2;
517
+ break;
518
+ }
519
+
520
+ new Effect.MoveBy(element, initialMoveY, initialMoveX, {
521
+ duration: 0.01,
522
+ beforeUpdate: function(effect) { $(element).style.height = '0px'; },
523
+ afterFinish: function(effect) {
524
+ new Effect.Parallel(
525
+ [ new Effect.Opacity(element, { sync: true, to: 1.0, from: 0.0, transition: opacityTransition }),
526
+ new Effect.MoveBy(element, moveY, moveX, { sync: true, transition: moveTransition }),
527
+ new Effect.Scale(element, 100, {
528
+ scaleMode: { originalHeight: originalHeight, originalWidth: originalWidth },
529
+ sync: true, scaleFrom: 0, scaleTo: 100, transition: scaleTransition })],
530
+ options); }
531
+ });
532
+ }
533
+
534
+ Effect.Shrink = function(element) {
535
+ element = $(element);
536
+ var options = arguments[1] || {};
537
+
538
+ var originalWidth = element.clientWidth;
539
+ var originalHeight = element.clientHeight;
540
+ element.style.overflow = 'hidden';
541
+ Element.show(element);
542
+
543
+ var direction = options.direction || 'center';
544
+ var moveTransition = options.moveTransition || Effect.Transitions.sinoidal;
545
+ var scaleTransition = options.scaleTransition || Effect.Transitions.sinoidal;
546
+ var opacityTransition = options.opacityTransition || Effect.Transitions.none;
547
+
548
+ var moveX, moveY;
549
+
550
+ switch (direction) {
551
+ case 'top-left':
552
+ moveX = moveY = 0;
553
+ break;
554
+ case 'top-right':
555
+ moveX = originalWidth;
556
+ moveY = 0;
557
+ break;
558
+ case 'bottom-left':
559
+ moveX = 0;
560
+ moveY = originalHeight;
561
+ break;
562
+ case 'bottom-right':
563
+ moveX = originalWidth;
564
+ moveY = originalHeight;
565
+ break;
566
+ case 'center':
567
+ moveX = originalWidth / 2;
568
+ moveY = originalHeight / 2;
569
+ break;
570
+ }
571
+
572
+ new Effect.Parallel(
573
+ [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: opacityTransition }),
574
+ new Effect.Scale(element, 0, { sync: true, transition: moveTransition }),
575
+ new Effect.MoveBy(element, moveY, moveX, { sync: true, transition: scaleTransition }) ],
576
+ options);
577
+ }
578
+
579
+ Effect.Pulsate = function(element) {
580
+ var options = arguments[1] || {};
581
+ var transition = options.transition || Effect.Transitions.sinoidal;
582
+ var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) };
583
+ reverser.bind(transition);
584
+ new Effect.Opacity(element,
585
+ Object.extend(Object.extend({ duration: 3.0,
586
+ afterFinish: function(effect) { Element.show(effect.element); }
587
+ }, options), {transition: reverser}));
588
+ }
589
+
590
+ Effect.Fold = function(element) {
591
+ $(element).style.overflow = 'hidden';
592
+ new Effect.Scale(element, 5, Object.extend({
593
+ scaleContent: false,
594
+ scaleTo: 100,
595
+ scaleX: false,
596
+ afterFinish: function(effect) {
597
+ new Effect.Scale(element, 1, {
598
+ scaleContent: false,
599
+ scaleTo: 0,
600
+ scaleY: false,
601
+ afterFinish: function(effect) { Element.hide(effect.element) } });
602
+ }}, arguments[1] || {}));
603
+ }
604
+
605
+ // old: new Effect.ContentZoom(element, percent)
606
+ // new: Element.setContentZoom(element, percent)
607
+
608
+ Element.setContentZoom = function(element, percent) {
609
+ var element = $(element);
610
+ element.style.fontSize = (percent/100) + "em";
611
+ if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
612
+ }