nitro 0.23.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. data/CHANGELOG +350 -0
  2. data/INSTALL +2 -2
  3. data/ProjectInfo +61 -0
  4. data/README +5 -4
  5. data/Rakefile +5 -4
  6. data/bin/nitrogen +3 -1
  7. data/doc/AUTHORS +27 -3
  8. data/doc/RELEASES +193 -0
  9. data/doc/lhttpd.txt +4 -0
  10. data/lib/nitro.rb +1 -1
  11. data/lib/nitro/adapter/cgi.rb +6 -321
  12. data/lib/nitro/adapter/fastcgi.rb +2 -14
  13. data/lib/nitro/adapter/scgi.rb +237 -71
  14. data/lib/nitro/adapter/webrick.rb +25 -7
  15. data/lib/nitro/caching.rb +1 -0
  16. data/lib/nitro/cgi.rb +296 -0
  17. data/lib/nitro/{cookie.rb → cgi/cookie.rb} +0 -0
  18. data/lib/nitro/cgi/http.rb +62 -0
  19. data/lib/nitro/{request.rb → cgi/request.rb} +4 -1
  20. data/lib/nitro/{response.rb → cgi/response.rb} +0 -0
  21. data/lib/nitro/cgi/stream.rb +43 -0
  22. data/lib/nitro/cgi/utils.rb +38 -0
  23. data/lib/nitro/compiler.rb +23 -11
  24. data/lib/nitro/compiler/css.rb +8 -0
  25. data/lib/nitro/compiler/morphing.rb +66 -0
  26. data/lib/nitro/context.rb +21 -30
  27. data/lib/nitro/controller.rb +23 -100
  28. data/lib/nitro/dispatcher.rb +18 -8
  29. data/lib/nitro/element.rb +6 -2
  30. data/lib/nitro/flash.rb +2 -2
  31. data/lib/nitro/mixin/buffer.rb +2 -2
  32. data/lib/nitro/mixin/form.rb +204 -93
  33. data/lib/nitro/mixin/javascript.rb +170 -11
  34. data/lib/nitro/mixin/markup.rb +1 -0
  35. data/lib/nitro/mixin/pager.rb +7 -4
  36. data/lib/nitro/mixin/rss.rb +2 -0
  37. data/lib/nitro/mixin/table.rb +23 -6
  38. data/lib/nitro/mixin/xhtml.rb +2 -2
  39. data/lib/nitro/render.rb +19 -5
  40. data/lib/nitro/scaffold.rb +12 -6
  41. data/lib/nitro/server.rb +4 -6
  42. data/lib/nitro/server/runner.rb +2 -2
  43. data/lib/nitro/session.rb +8 -1
  44. data/lib/nitro/session/file.rb +40 -0
  45. data/lib/part/admin.rb +2 -0
  46. data/lib/part/admin/controller.rb +7 -3
  47. data/lib/part/admin/skin.rb +8 -1
  48. data/lib/part/admin/template/index.xhtml +39 -1
  49. data/proto/public/error.xhtml +5 -3
  50. data/proto/public/js/behaviour.js +254 -254
  51. data/proto/public/js/controls.js +427 -165
  52. data/proto/public/js/dragdrop.js +255 -276
  53. data/proto/public/js/effects.js +476 -277
  54. data/proto/public/js/prototype.js +561 -127
  55. data/proto/public/js/scaffold.js +74 -0
  56. data/proto/public/js/scriptaculous.js +44 -0
  57. data/proto/public/js/util.js +548 -0
  58. data/proto/public/scaffold/list.xhtml +4 -1
  59. data/proto/scgi.rb +333 -0
  60. data/script/scgi_ctl +221 -0
  61. data/script/scgi_service +120 -0
  62. data/test/nitro/adapter/raw_post1.bin +0 -0
  63. data/test/nitro/{tc_cookie.rb → cgi/tc_cookie.rb} +1 -1
  64. data/test/nitro/{tc_request.rb → cgi/tc_request.rb} +1 -1
  65. data/test/nitro/mixin/tc_xhtml.rb +1 -1
  66. data/test/nitro/{adapter/tc_cgi.rb → tc_cgi.rb} +12 -12
  67. data/test/nitro/tc_controller.rb +9 -5
  68. metadata +159 -169
  69. data/benchmark/bench.rb +0 -5
  70. data/benchmark/simple-webrick-n-200.txt +0 -44
  71. data/benchmark/static-webrick-n-200.txt +0 -43
  72. data/benchmark/tiny-lhttpd-n-200-c-5.txt +0 -43
  73. data/benchmark/tiny-webrick-n-200-c-5.txt +0 -44
  74. data/benchmark/tiny-webrick-n-200.txt +0 -44
  75. data/benchmark/tiny2-webrick-n-200.txt +0 -44
  76. data/examples/README +0 -7
@@ -1,30 +1,51 @@
1
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/)
2
+ // Contributors:
3
+ // Justin Palmer (http://encytemedia.com/)
4
+ // Mark Pilgrim (http://diveintomark.org/)
5
+ // Martin Bialasinki
5
6
  //
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.
7
+ // See scriptaculous.js for full license.
8
+
9
+ var Effect = {
10
+ tagifyText: function(element) {
11
+ var tagifyStyle = "position:relative";
12
+ if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ";zoom:1";
13
+ element = $(element);
14
+ $A(element.childNodes).each( function(child) {
15
+ if(child.nodeType==3) {
16
+ child.nodeValue.toArray().each( function(character) {
17
+ element.insertBefore(
18
+ Builder.node('span',{style: tagifyStyle},
19
+ character == " " ? String.fromCharCode(160) : character),
20
+ child);
21
+ });
22
+ Element.remove(child);
23
+ }
24
+ });
25
+ },
26
+ multiple: function(element, effect) {
27
+ var elements;
28
+ if(((typeof element == 'object') ||
29
+ (typeof element == 'function')) &&
30
+ (element.length))
31
+ elements = element;
32
+ else
33
+ elements = $(element).childNodes;
34
+
35
+ var options = Object.extend({
36
+ speed: 0.1,
37
+ delay: 0.0
38
+ }, arguments[2] || {});
39
+ var speed = options.speed;
40
+ var delay = options.delay;
24
41
 
42
+ $A(elements).each( function(element, index) {
43
+ new effect(element, Object.extend(options, { delay: delay + index * speed }));
44
+ });
45
+ }
46
+ };
25
47
 
26
- Effect = {}
27
- Effect2 = Effect; // deprecated
48
+ var Effect2 = Effect; // deprecated
28
49
 
29
50
  /* ------------- transitions ------------- */
30
51
 
@@ -40,7 +61,7 @@ Effect.Transitions.reverse = function(pos) {
40
61
  return 1-pos;
41
62
  }
42
63
  Effect.Transitions.flicker = function(pos) {
43
- return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random(0.25);
64
+ return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
44
65
  }
45
66
  Effect.Transitions.wobble = function(pos) {
46
67
  return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
@@ -56,73 +77,111 @@ Effect.Transitions.full = function(pos) {
56
77
  return 1;
57
78
  }
58
79
 
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
- }
80
+ /* ------------- core effects ------------- */
72
81
 
73
- Element.undoClipping = function(element) {
74
- element = $(element);
75
- if(element._overflow!='hidden') element.style.overflow = element._overflow;
82
+ Effect.Queue = {
83
+ effects: [],
84
+ interval: null,
85
+ add: function(effect) {
86
+ var timestamp = new Date().getTime();
87
+
88
+ switch(effect.options.queue) {
89
+ case 'front':
90
+ // move unstarted effects after this effect
91
+ this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
92
+ e.startOn += effect.finishOn;
93
+ e.finishOn += effect.finishOn;
94
+ });
95
+ break;
96
+ case 'end':
97
+ // start effect after last queued effect has finished
98
+ timestamp = this.effects.pluck('finishOn').max() || timestamp;
99
+ break;
100
+ }
101
+
102
+ effect.startOn += timestamp;
103
+ effect.finishOn += timestamp;
104
+ this.effects.push(effect);
105
+ if(!this.interval)
106
+ this.interval = setInterval(this.loop.bind(this), 40);
107
+ },
108
+ remove: function(effect) {
109
+ this.effects = this.effects.reject(function(e) { return e==effect });
110
+ if(this.effects.length == 0) {
111
+ clearInterval(this.interval);
112
+ this.interval = null;
113
+ }
114
+ },
115
+ loop: function() {
116
+ var timePos = new Date().getTime();
117
+ this.effects.invoke('loop', timePos);
118
+ }
76
119
  }
77
120
 
78
- /* ------------- core effects ------------- */
79
-
80
121
  Effect.Base = function() {};
81
122
  Effect.Base.prototype = {
123
+ position: null,
82
124
  setOptions: function(options) {
83
125
  this.options = Object.extend({
84
126
  transition: Effect.Transitions.sinoidal,
85
127
  duration: 1.0, // seconds
86
- fps: 25.0, // max. 100fps
128
+ fps: 25.0, // max. 25fps due to Effect.Queue implementation
87
129
  sync: false, // true for combining
88
130
  from: 0.0,
89
- to: 1.0
131
+ to: 1.0,
132
+ delay: 0.0,
133
+ queue: 'parallel'
90
134
  }, options || {});
91
135
  },
92
136
  start: function(options) {
93
137
  this.setOptions(options || {});
94
138
  this.currentFrame = 0;
95
- this.startOn = new Date().getTime();
139
+ this.state = 'idle';
140
+ this.startOn = this.options.delay*1000;
96
141
  this.finishOn = this.startOn + (this.options.duration*1000);
97
- if(this.options.beforeStart) this.options.beforeStart(this);
98
- if(!this.options.sync) this.loop();
142
+ this.event('beforeStart');
143
+ if(!this.options.sync) Effect.Queue.add(this);
99
144
  },
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;
145
+ loop: function(timePos) {
146
+ if(timePos >= this.startOn) {
147
+ if(timePos >= this.finishOn) {
148
+ this.render(1.0);
149
+ this.cancel();
150
+ this.event('beforeFinish');
151
+ if(this.finish) this.finish();
152
+ this.event('afterFinish');
153
+ return;
154
+ }
155
+ var pos = (timePos - this.startOn) / (this.finishOn - this.startOn);
156
+ var frame = Math.round(pos * this.options.fps * this.options.duration);
157
+ if(frame > this.currentFrame) {
158
+ this.render(pos);
159
+ this.currentFrame = frame;
160
+ }
113
161
  }
114
- this.timeout = setTimeout(this.loop.bind(this), 10);
115
162
  },
116
163
  render: function(pos) {
164
+ if(this.state == 'idle') {
165
+ this.state = 'running';
166
+ this.event('beforeSetup');
167
+ if(this.setup) this.setup();
168
+ this.event('afterSetup');
169
+ }
117
170
  if(this.options.transition) pos = this.options.transition(pos);
118
171
  pos *= (this.options.to-this.options.from);
119
- pos += this.options.from;
120
- if(this.options.beforeUpdate) this.options.beforeUpdate(this);
172
+ pos += this.options.from;
173
+ this.position = pos;
174
+ this.event('beforeUpdate');
121
175
  if(this.update) this.update(pos);
122
- if(this.options.afterUpdate) this.options.afterUpdate(this);
176
+ this.event('afterUpdate');
123
177
  },
124
178
  cancel: function() {
125
- if(this.timeout) clearTimeout(this.timeout);
179
+ if(!this.options.sync) Effect.Queue.remove(this);
180
+ this.state = 'finished';
181
+ },
182
+ event: function(eventName) {
183
+ if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
184
+ if(this.options[eventName]) this.options[eventName](this);
126
185
  }
127
186
  }
128
187
 
@@ -133,35 +192,34 @@ Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
133
192
  this.start(arguments[1]);
134
193
  },
135
194
  update: function(position) {
136
- for (var i = 0; i < this.effects.length; i++)
137
- this.effects[i].render(position);
195
+ this.effects.invoke('render', position);
138
196
  },
139
197
  finish: function(position) {
140
- for (var i = 0; i < this.effects.length; i++)
141
- if(this.effects[i].finish) this.effects[i].finish(position);
198
+ this.effects.each( function(effect) {
199
+ effect.render(1.0);
200
+ effect.cancel();
201
+ effect.event('beforeFinish');
202
+ if(effect.finish) effect.finish(position);
203
+ effect.event('afterFinish');
204
+ });
142
205
  }
143
206
  });
144
207
 
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
208
  Effect.Opacity = Class.create();
149
209
  Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
150
210
  initialize: function(element) {
151
211
  this.element = $(element);
152
- options = Object.extend({
153
- from: 0.0,
212
+ // make this work on IE on elements without 'layout'
213
+ if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout))
214
+ this.element.style.zoom = 1;
215
+ var options = Object.extend({
216
+ from: Element.getOpacity(this.element) || 0.0,
154
217
  to: 1.0
155
218
  }, arguments[1] || {});
156
219
  this.start(options);
157
220
  },
158
221
  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+")";
222
+ Element.setOpacity(this.element, position);
165
223
  }
166
224
  });
167
225
 
@@ -169,16 +227,23 @@ Effect.MoveBy = Class.create();
169
227
  Object.extend(Object.extend(Effect.MoveBy.prototype, Effect.Base.prototype), {
170
228
  initialize: function(element, toTop, toLeft) {
171
229
  this.element = $(element);
172
- this.originalTop = parseFloat(this.element.style.top || '0');
173
- this.originalLeft = parseFloat(this.element.style.left || '0');
174
230
  this.toTop = toTop;
175
231
  this.toLeft = toLeft;
176
- Element.makePositioned(this.element);
177
232
  this.start(arguments[3]);
178
233
  },
234
+ setup: function() {
235
+ // Bug in Opera: Opera returns the "real" position of a static element or
236
+ // relative element that does not have top/left explicitly set.
237
+ // ==> Always set top and left for position relative elements in your stylesheets
238
+ // (to 0 if you do not need them)
239
+
240
+ Element.makePositioned(this.element);
241
+ this.originalTop = parseFloat(Element.getStyle(this.element,'top') || '0');
242
+ this.originalLeft = parseFloat(Element.getStyle(this.element,'left') || '0');
243
+ },
179
244
  update: function(position) {
180
- topd = this.toTop * position + this.originalTop;
181
- leftd = this.toLeft * position + this.originalLeft;
245
+ var topd = this.toTop * position + this.originalTop;
246
+ var leftd = this.toLeft * position + this.originalLeft;
182
247
  this.setPosition(topd, leftd);
183
248
  },
184
249
  setPosition: function(topd, leftd) {
@@ -191,55 +256,77 @@ Effect.Scale = Class.create();
191
256
  Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
192
257
  initialize: function(element, percent) {
193
258
  this.element = $(element)
194
- options = Object.extend({
259
+ var options = Object.extend({
195
260
  scaleX: true,
196
261
  scaleY: true,
197
262
  scaleContent: true,
198
263
  scaleFromCenter: false,
199
264
  scaleMode: 'box', // 'box' or 'contents' or {} with provided values
200
- scaleFrom: 100.0
265
+ scaleFrom: 100.0,
266
+ scaleTo: percent
201
267
  }, 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
268
  this.start(options);
220
269
  },
221
-
270
+ setup: function() {
271
+ var effect = this;
272
+
273
+ this.restoreAfterFinish = this.options.restoreAfterFinish || false;
274
+ this.elementPositioning = Element.getStyle(this.element,'position');
275
+
276
+ effect.originalStyle = {};
277
+ ['top','left','width','height','fontSize'].each( function(k) {
278
+ effect.originalStyle[k] = effect.element.style[k];
279
+ });
280
+
281
+ this.originalTop = this.element.offsetTop;
282
+ this.originalLeft = this.element.offsetLeft;
283
+
284
+ var fontSize = Element.getStyle(this.element,'font-size') || "100%";
285
+ ['em','px','%'].each( function(fontSizeType) {
286
+ if(fontSize.indexOf(fontSizeType)>0) {
287
+ effect.fontSize = parseFloat(fontSize);
288
+ effect.fontSizeType = fontSizeType;
289
+ }
290
+ });
291
+
292
+ this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
293
+
294
+ this.dims = null;
295
+ if(this.options.scaleMode=='box')
296
+ this.dims = [this.element.clientHeight, this.element.clientWidth];
297
+ if(this.options.scaleMode=='content')
298
+ this.dims = [this.element.scrollHeight, this.element.scrollWidth];
299
+ if(!this.dims)
300
+ this.dims = [this.options.scaleMode.originalHeight,
301
+ this.options.scaleMode.originalWidth];
302
+ },
222
303
  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);
304
+ var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
305
+ if(this.options.scaleContent && this.fontSize)
306
+ this.element.style.fontSize = this.fontSize*currentScale + this.fontSizeType;
307
+ this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
229
308
  },
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';
309
+ finish: function(position) {
310
+ if (this.restoreAfterFinish) {
311
+ var effect = this;
312
+ ['top','left','width','height','fontSize'].each( function(k) {
313
+ effect.element.style[k] = effect.originalStyle[k];
314
+ });
315
+ }
316
+ },
317
+ setDimensions: function(height, width) {
318
+ var els = this.element.style;
319
+ if(this.options.scaleX) els.width = width + 'px';
320
+ if(this.options.scaleY) els.height = height + 'px';
234
321
  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";
322
+ var topd = (height - this.dims[0])/2;
323
+ var leftd = (width - this.dims[1])/2;
324
+ if(this.elementPositioning == 'absolute') {
325
+ if(this.options.scaleY) els.top = this.originalTop-topd + "px";
326
+ if(this.options.scaleX) els.left = this.originalLeft-leftd + "px";
240
327
  } else {
241
- if(this.options.scaleY) this.element.style.top = -topd + "px";
242
- if(this.options.scaleX) this.element.style.left = -leftd + "px";
328
+ if(this.options.scaleY) els.top = -topd + "px";
329
+ if(this.options.scaleX) els.left = -leftd + "px";
243
330
  }
244
331
  }
245
332
  }
@@ -249,44 +336,39 @@ Effect.Highlight = Class.create();
249
336
  Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
250
337
  initialize: function(element) {
251
338
  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
339
  var options = Object.extend({
263
- startcolor: "#ffff99",
264
- endcolor: endcolor,
265
- restorecolor: current
340
+ startcolor: "#ffff99"
266
341
  }, arguments[1] || {});
267
-
342
+ this.start(options);
343
+ },
344
+ setup: function() {
345
+ // Disable background image during the effect
346
+ this.oldBgImage = this.element.style.backgroundImage;
347
+ this.element.style.backgroundImage = "none";
348
+ if(!this.options.endcolor)
349
+ this.options.endcolor = Element.getStyle(this.element, 'background-color').parseColor('#ffffff');
350
+ if (typeof this.options.restorecolor == "undefined")
351
+ this.options.restorecolor = this.element.style.backgroundColor;
268
352
  // init color calculations
269
353
  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) ];
354
+ parseInt(this.options.startcolor.slice(1,3),16),
355
+ parseInt(this.options.startcolor.slice(3,5),16),
356
+ parseInt(this.options.startcolor.slice(5),16) ];
273
357
  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);
358
+ parseInt(this.options.endcolor.slice(1,3),16)-this.colors_base[0],
359
+ parseInt(this.options.endcolor.slice(3,5),16)-this.colors_base[1],
360
+ parseInt(this.options.endcolor.slice(5),16)-this.colors_base[2]];
279
361
  },
280
362
  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)) ];
363
+ var effect = this; var colors = $R(0,2).map( function(i){
364
+ return Math.round(effect.colors_base[i]+(effect.colors_delta[i]*position))
365
+ });
285
366
  this.element.style.backgroundColor = "#" +
286
367
  colors[0].toColorPart() + colors[1].toColorPart() + colors[2].toColorPart();
287
368
  },
288
369
  finish: function() {
289
370
  this.element.style.backgroundColor = this.options.restorecolor;
371
+ this.element.style.backgroundImage = this.oldBgImage;
290
372
  }
291
373
  });
292
374
 
@@ -294,6 +376,9 @@ Effect.ScrollTo = Class.create();
294
376
  Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
295
377
  initialize: function(element) {
296
378
  this.element = $(element);
379
+ this.start(arguments[1] || {});
380
+ },
381
+ setup: function() {
297
382
  Position.prepare();
298
383
  var offsets = Position.cumulativeOffset(this.element);
299
384
  var max = window.innerHeight ?
@@ -302,8 +387,7 @@ Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
302
387
  (document.documentElement.clientHeight ?
303
388
  document.documentElement.clientHeight : document.body.clientHeight);
304
389
  this.scrollStart = Position.deltaY;
305
- this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
306
- this.start(arguments[1] || {});
390
+ this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
307
391
  },
308
392
  update: function(position) {
309
393
  Position.prepare();
@@ -312,51 +396,61 @@ Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
312
396
  }
313
397
  });
314
398
 
315
- /* ------------- prepackaged effects ------------- */
399
+ /* ------------- combination effects ------------- */
316
400
 
317
401
  Effect.Fade = function(element) {
318
- options = Object.extend({
319
- from: 1.0,
402
+ var oldOpacity = Element.getInlineOpacity(element);
403
+ var options = Object.extend({
404
+ from: Element.getOpacity(element) || 1.0,
320
405
  to: 0.0,
321
- afterFinish: function(effect)
322
- { Element.hide(effect.element);
323
- effect.setOpacity(1); }
406
+ afterFinishInternal: function(effect)
407
+ { if (effect.options.to == 0) {
408
+ Element.hide(effect.element);
409
+ Element.setInlineOpacity(effect.element, oldOpacity);
410
+ }
411
+ }
324
412
  }, arguments[1] || {});
325
- new Effect.Opacity(element,options);
413
+ return new Effect.Opacity(element,options);
326
414
  }
327
415
 
328
416
  Effect.Appear = function(element) {
329
- options = Object.extend({
330
- from: 0.0,
417
+ var options = Object.extend({
418
+ from: (Element.getStyle(element, "display") == "none" ? 0.0 : Element.getOpacity(element) || 0.0),
331
419
  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); }
420
+ beforeSetup: function(effect)
421
+ { Element.setOpacity(effect.element, effect.options.from);
422
+ Element.show(effect.element); }
337
423
  }, arguments[1] || {});
338
- new Effect.Opacity(element,options);
424
+ return new Effect.Opacity(element,options);
339
425
  }
340
426
 
341
427
  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)
428
+ element = $(element);
429
+ var oldOpacity = Element.getInlineOpacity(element);
430
+ var oldPosition = element.style.position;
431
+ return new Effect.Parallel(
432
+ [ new Effect.Scale(element, 200,
433
+ { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
434
+ new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
435
+ Object.extend({ duration: 1.0,
436
+ beforeSetupInternal: function(effect)
347
437
  { effect.effects[0].element.style.position = 'absolute'; },
348
- afterFinish: function(effect)
349
- { Element.hide(effect.effects[0].element); }
350
- }
438
+ afterFinishInternal: function(effect)
439
+ { Element.hide(effect.effects[0].element);
440
+ effect.effects[0].element.style.position = oldPosition;
441
+ Element.setInlineOpacity(effect.effects[0].element, oldOpacity); }
442
+ }, arguments[1] || {})
351
443
  );
352
444
  }
353
445
 
354
446
  Effect.BlindUp = function(element) {
447
+ element = $(element);
355
448
  Element.makeClipping(element);
356
- new Effect.Scale(element, 0,
449
+ return new Effect.Scale(element, 0,
357
450
  Object.extend({ scaleContent: false,
358
451
  scaleX: false,
359
- afterFinish: function(effect)
452
+ restoreAfterFinish: true,
453
+ afterFinishInternal: function(effect)
360
454
  {
361
455
  Element.hide(effect.element);
362
456
  Element.undoClipping(effect.element);
@@ -366,120 +460,179 @@ Effect.BlindUp = function(element) {
366
460
  }
367
461
 
368
462
  Effect.BlindDown = function(element) {
369
- $(element).style.height = '0px';
370
- Element.makeClipping(element);
371
- Element.show(element);
372
- new Effect.Scale(element, 100,
463
+ element = $(element);
464
+ var oldHeight = element.style.height;
465
+ var elementDimensions = Element.getDimensions(element);
466
+ return new Effect.Scale(element, 100,
373
467
  Object.extend({ scaleContent: false,
374
- scaleX: false,
375
- scaleMode: 'contents',
468
+ scaleX: false,
376
469
  scaleFrom: 0,
377
- afterFinish: function(effect) {
470
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
471
+ restoreAfterFinish: true,
472
+ afterSetup: function(effect) {
473
+ Element.makeClipping(effect.element);
474
+ effect.element.style.height = "0px";
475
+ Element.show(effect.element);
476
+ },
477
+ afterFinishInternal: function(effect) {
378
478
  Element.undoClipping(effect.element);
479
+ effect.element.style.height = oldHeight;
379
480
  }
380
481
  }, arguments[1] || {})
381
482
  );
382
483
  }
383
484
 
384
485
  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
- } );
486
+ element = $(element);
487
+ var oldOpacity = Element.getInlineOpacity(element);
488
+ return new Effect.Appear(element, {
489
+ duration: 0.4,
490
+ from: 0,
491
+ transition: Effect.Transitions.flicker,
492
+ afterFinishInternal: function(effect) {
493
+ new Effect.Scale(effect.element, 1, {
494
+ duration: 0.3, scaleFromCenter: true,
495
+ scaleX: false, scaleContent: false, restoreAfterFinish: true,
496
+ beforeSetup: function(effect) {
497
+ Element.makePositioned(effect.element);
498
+ Element.makeClipping(effect.element);
499
+ },
500
+ afterFinishInternal: function(effect) {
501
+ Element.hide(effect.element);
502
+ Element.undoClipping(effect.element);
503
+ Element.undoPositioned(effect.element);
504
+ Element.setInlineOpacity(effect.element, oldOpacity);
505
+ }
506
+ })
507
+ }
508
+ });
400
509
  }
401
510
 
402
511
  Effect.DropOut = function(element) {
403
- new Effect.Parallel(
512
+ element = $(element);
513
+ var oldTop = element.style.top;
514
+ var oldLeft = element.style.left;
515
+ var oldOpacity = Element.getInlineOpacity(element);
516
+ return new Effect.Parallel(
404
517
  [ 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
- });
518
+ new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
519
+ Object.extend(
520
+ { duration: 0.5,
521
+ beforeSetup: function(effect) {
522
+ Element.makePositioned(effect.effects[0].element); },
523
+ afterFinishInternal: function(effect) {
524
+ Element.hide(effect.effects[0].element);
525
+ Element.undoPositioned(effect.effects[0].element);
526
+ effect.effects[0].element.style.left = oldLeft;
527
+ effect.effects[0].element.style.top = oldTop;
528
+ Element.setInlineOpacity(effect.effects[0].element, oldOpacity); }
529
+ }, arguments[1] || {}));
410
530
  }
411
531
 
412
532
  Effect.Shake = function(element) {
413
- new Effect.MoveBy(element, 0, 20,
414
- { duration: 0.05, afterFinish: function(effect) {
533
+ element = $(element);
534
+ var oldTop = element.style.top;
535
+ var oldLeft = element.style.left;
536
+ return new Effect.MoveBy(element, 0, 20,
537
+ { duration: 0.05, afterFinishInternal: function(effect) {
415
538
  new Effect.MoveBy(effect.element, 0, -40,
416
- { duration: 0.1, afterFinish: function(effect) {
539
+ { duration: 0.1, afterFinishInternal: function(effect) {
417
540
  new Effect.MoveBy(effect.element, 0, 40,
418
- { duration: 0.1, afterFinish: function(effect) {
541
+ { duration: 0.1, afterFinishInternal: function(effect) {
419
542
  new Effect.MoveBy(effect.element, 0, -40,
420
- { duration: 0.1, afterFinish: function(effect) {
543
+ { duration: 0.1, afterFinishInternal: function(effect) {
421
544
  new Effect.MoveBy(effect.element, 0, 40,
422
- { duration: 0.1, afterFinish: function(effect) {
545
+ { duration: 0.1, afterFinishInternal: function(effect) {
423
546
  new Effect.MoveBy(effect.element, 0, -20,
424
- { duration: 0.05, afterFinish: function(effect) {
547
+ { duration: 0.05, afterFinishInternal: function(effect) {
548
+ Element.undoPositioned(effect.element);
549
+ effect.element.style.left = oldLeft;
550
+ effect.element.style.top = oldTop;
425
551
  }}) }}) }}) }}) }}) }});
426
552
  }
427
553
 
428
554
  Effect.SlideDown = function(element) {
429
555
  element = $(element);
430
- element.style.height = '0px';
431
- Element.makeClipping(element);
432
556
  Element.cleanWhitespace(element);
433
- Element.makePositioned(element.firstChild);
434
- Element.show(element);
435
- new Effect.Scale(element, 100,
557
+ // SlideDown need to have the content of the element wrapped in a container element with fixed height!
558
+ var oldInnerBottom = element.firstChild.style.bottom;
559
+ var elementDimensions = Element.getDimensions(element);
560
+ return new Effect.Scale(element, 100,
436
561
  Object.extend({ scaleContent: false,
437
562
  scaleX: false,
438
- scaleMode: 'contents',
439
563
  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); }
564
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
565
+ restoreAfterFinish: true,
566
+ afterSetup: function(effect) {
567
+ Element.makePositioned(effect.element.firstChild);
568
+ if (window.opera) effect.element.firstChild.style.top = "";
569
+ Element.makeClipping(effect.element);
570
+ element.style.height = '0';
571
+ Element.show(element);
572
+ },
573
+ afterUpdateInternal: function(effect) {
574
+ effect.element.firstChild.style.bottom =
575
+ (effect.originalHeight - effect.element.clientHeight) + 'px'; },
576
+ afterFinishInternal: function(effect) {
577
+ Element.undoClipping(effect.element);
578
+ Element.undoPositioned(effect.element.firstChild);
579
+ effect.element.firstChild.style.bottom = oldInnerBottom; }
445
580
  }, arguments[1] || {})
446
581
  );
447
582
  }
448
583
 
449
584
  Effect.SlideUp = function(element) {
450
585
  element = $(element);
451
- Element.makeClipping(element);
452
586
  Element.cleanWhitespace(element);
453
- Element.makePositioned(element.firstChild);
454
- Element.show(element);
455
- new Effect.Scale(element, 0,
587
+ var oldInnerBottom = element.firstChild.style.bottom;
588
+ return new Effect.Scale(element, 0,
456
589
  Object.extend({ scaleContent: false,
457
590
  scaleX: false,
458
- afterUpdate: function(effect)
459
- { effect.element.firstChild.style.bottom =
460
- (effect.originalHeight - effect.element.clientHeight) + 'px'; },
461
- afterFinish: function(effect)
462
- {
591
+ scaleMode: 'box',
592
+ scaleFrom: 100,
593
+ restoreAfterFinish: true,
594
+ beforeStartInternal: function(effect) {
595
+ Element.makePositioned(effect.element.firstChild);
596
+ if (window.opera) effect.element.firstChild.style.top = "";
597
+ Element.makeClipping(effect.element);
598
+ Element.show(element);
599
+ },
600
+ afterUpdateInternal: function(effect) {
601
+ effect.element.firstChild.style.bottom =
602
+ (effect.originalHeight - effect.element.clientHeight) + 'px'; },
603
+ afterFinishInternal: function(effect) {
463
604
  Element.hide(effect.element);
464
- Element.undoClipping(effect.element);
465
- }
605
+ Element.undoClipping(effect.element);
606
+ Element.undoPositioned(effect.element.firstChild);
607
+ effect.element.firstChild.style.bottom = oldInnerBottom; }
466
608
  }, arguments[1] || {})
467
609
  );
468
610
  }
469
611
 
470
612
  Effect.Squish = function(element) {
471
- new Effect.Scale(element, 0,
472
- { afterFinish: function(effect) { Element.hide(effect.element); } });
613
+ // Bug in opera makes the TD containing this element expand for a instance after finish
614
+ return new Effect.Scale(element, window.opera ? 1 : 0,
615
+ { restoreAfterFinish: true,
616
+ beforeSetup: function(effect) {
617
+ Element.makeClipping(effect.element); },
618
+ afterFinishInternal: function(effect) {
619
+ Element.hide(effect.element);
620
+ Element.undoClipping(effect.element); }
621
+ });
473
622
  }
474
623
 
475
624
  Effect.Grow = function(element) {
476
625
  element = $(element);
477
626
  var options = arguments[1] || {};
478
627
 
479
- var originalWidth = element.clientWidth;
480
- var originalHeight = element.clientHeight;
481
- element.style.overflow = 'hidden';
482
- Element.show(element);
628
+ var elementDimensions = Element.getDimensions(element);
629
+ var originalWidth = elementDimensions.width;
630
+ var originalHeight = elementDimensions.height;
631
+ var oldTop = element.style.top;
632
+ var oldLeft = element.style.left;
633
+ var oldHeight = element.style.height;
634
+ var oldWidth = element.style.width;
635
+ var oldOpacity = Element.getInlineOpacity(element);
483
636
 
484
637
  var direction = options.direction || 'center';
485
638
  var moveTransition = options.moveTransition || Effect.Transitions.sinoidal;
@@ -517,18 +670,40 @@ Effect.Grow = function(element) {
517
670
  break;
518
671
  }
519
672
 
520
- new Effect.MoveBy(element, initialMoveY, initialMoveX, {
673
+ return new Effect.MoveBy(element, initialMoveY, initialMoveX, {
521
674
  duration: 0.01,
522
- beforeUpdate: function(effect) { $(element).style.height = '0px'; },
523
- afterFinish: function(effect) {
675
+ beforeSetup: function(effect) {
676
+ Element.hide(effect.element);
677
+ Element.makeClipping(effect.element);
678
+ Element.makePositioned(effect.element);
679
+ },
680
+ afterFinishInternal: function(effect) {
524
681
  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, {
682
+ [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: opacityTransition }),
683
+ new Effect.MoveBy(effect.element, moveY, moveX, { sync: true, transition: moveTransition }),
684
+ new Effect.Scale(effect.element, 100, {
528
685
  scaleMode: { originalHeight: originalHeight, originalWidth: originalWidth },
529
- sync: true, scaleFrom: 0, scaleTo: 100, transition: scaleTransition })],
530
- options); }
531
- });
686
+ sync: true, scaleFrom: window.opera ? 1 : 0, transition: scaleTransition, restoreAfterFinish: true})
687
+ ], Object.extend({
688
+ beforeSetup: function(effect) {
689
+ effect.effects[0].element.style.height = 0;
690
+ Element.show(effect.effects[0].element);
691
+ },
692
+ afterFinishInternal: function(effect) {
693
+ var el = effect.effects[0].element;
694
+ var els = el.style;
695
+ Element.undoClipping(el);
696
+ Element.undoPositioned(el);
697
+ els.top = oldTop;
698
+ els.left = oldLeft;
699
+ els.height = oldHeight;
700
+ els.width = originalWidth;
701
+ Element.setInlineOpacity(el, oldOpacity);
702
+ }
703
+ }, options)
704
+ )
705
+ }
706
+ });
532
707
  }
533
708
 
534
709
  Effect.Shrink = function(element) {
@@ -537,8 +712,11 @@ Effect.Shrink = function(element) {
537
712
 
538
713
  var originalWidth = element.clientWidth;
539
714
  var originalHeight = element.clientHeight;
540
- element.style.overflow = 'hidden';
541
- Element.show(element);
715
+ var oldTop = element.style.top;
716
+ var oldLeft = element.style.left;
717
+ var oldHeight = element.style.height;
718
+ var oldWidth = element.style.width;
719
+ var oldOpacity = Element.getInlineOpacity(element);
542
720
 
543
721
  var direction = options.direction || 'center';
544
722
  var moveTransition = options.moveTransition || Effect.Transitions.sinoidal;
@@ -569,44 +747,65 @@ Effect.Shrink = function(element) {
569
747
  break;
570
748
  }
571
749
 
572
- new Effect.Parallel(
750
+ return new Effect.Parallel(
573
751
  [ 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);
752
+ new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: scaleTransition, restoreAfterFinish: true}),
753
+ new Effect.MoveBy(element, moveY, moveX, { sync: true, transition: moveTransition })
754
+ ], Object.extend({
755
+ beforeStartInternal: function(effect) {
756
+ Element.makePositioned(effect.effects[0].element);
757
+ Element.makeClipping(effect.effects[0].element);
758
+ },
759
+ afterFinishInternal: function(effect) {
760
+ var el = effect.effects[0].element;
761
+ var els = el.style;
762
+ Element.hide(el);
763
+ Element.undoClipping(el);
764
+ Element.undoPositioned(el);
765
+ els.top = oldTop;
766
+ els.left = oldLeft;
767
+ els.height = oldHeight;
768
+ els.width = oldWidth;
769
+ Element.setInlineOpacity(el, oldOpacity);
770
+ }
771
+ }, options)
772
+ );
577
773
  }
578
774
 
579
775
  Effect.Pulsate = function(element) {
776
+ element = $(element);
580
777
  var options = arguments[1] || {};
778
+ var oldOpacity = Element.getInlineOpacity(element);
581
779
  var transition = options.transition || Effect.Transitions.sinoidal;
582
780
  var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) };
583
781
  reverser.bind(transition);
584
- new Effect.Opacity(element,
585
- Object.extend(Object.extend({ duration: 3.0,
586
- afterFinish: function(effect) { Element.show(effect.element); }
782
+ return new Effect.Opacity(element,
783
+ Object.extend(Object.extend({ duration: 3.0, from: 0,
784
+ afterFinishInternal: function(effect) { Element.setInlineOpacity(effect.element, oldOpacity); }
587
785
  }, options), {transition: reverser}));
588
786
  }
589
787
 
590
788
  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);
789
+ element = $(element);
790
+ var originalTop = element.style.top;
791
+ var originalLeft = element.style.left;
792
+ var originalWidth = element.style.width;
793
+ var originalHeight = element.style.height;
794
+ Element.makeClipping(element);
795
+ return new Effect.Scale(element, 5, Object.extend({
796
+ scaleContent: false,
797
+ scaleX: false,
798
+ afterFinishInternal: function(effect) {
799
+ new Effect.Scale(element, 1, {
800
+ scaleContent: false,
801
+ scaleY: false,
802
+ afterFinishInternal: function(effect) {
803
+ Element.hide(effect.element);
804
+ Element.undoClipping(effect.element);
805
+ effect.element.style.top = originalTop;
806
+ effect.element.style.left = originalLeft;
807
+ effect.element.style.width = originalWidth;
808
+ effect.element.style.height = originalHeight;
809
+ } });
810
+ }}, arguments[1] || {}));
612
811
  }