actionpack 1.11.2 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (149) hide show
  1. data/CHANGELOG +392 -5
  2. data/lib/action_controller.rb +8 -4
  3. data/lib/action_controller/assertions.rb +9 -10
  4. data/lib/action_controller/base.rb +177 -88
  5. data/lib/action_controller/benchmarking.rb +5 -5
  6. data/lib/action_controller/caching.rb +44 -36
  7. data/lib/action_controller/cgi_ext/cgi_methods.rb +71 -6
  8. data/lib/action_controller/cgi_ext/cookie_performance_fix.rb +1 -1
  9. data/lib/action_controller/cgi_process.rb +36 -24
  10. data/lib/action_controller/components.rb +152 -52
  11. data/lib/action_controller/dependencies.rb +1 -1
  12. data/lib/action_controller/deprecated_redirects.rb +2 -2
  13. data/lib/action_controller/deprecated_request_methods.rb +34 -0
  14. data/lib/action_controller/filters.rb +59 -19
  15. data/lib/action_controller/flash.rb +53 -47
  16. data/lib/action_controller/helpers.rb +2 -2
  17. data/lib/action_controller/integration.rb +524 -0
  18. data/lib/action_controller/layout.rb +58 -23
  19. data/lib/action_controller/mime_responds.rb +163 -0
  20. data/lib/action_controller/mime_type.rb +142 -0
  21. data/lib/action_controller/pagination.rb +13 -7
  22. data/lib/action_controller/request.rb +59 -56
  23. data/lib/action_controller/rescue.rb +1 -1
  24. data/lib/action_controller/routing.rb +29 -10
  25. data/lib/action_controller/scaffolding.rb +8 -0
  26. data/lib/action_controller/session/active_record_store.rb +21 -10
  27. data/lib/action_controller/session/mem_cache_store.rb +18 -12
  28. data/lib/action_controller/session_management.rb +30 -11
  29. data/lib/action_controller/templates/rescues/_trace.rhtml +1 -1
  30. data/lib/action_controller/templates/scaffolds/layout.rhtml +4 -4
  31. data/lib/action_controller/templates/scaffolds/list.rhtml +1 -1
  32. data/lib/action_controller/test_process.rb +189 -118
  33. data/lib/action_controller/vendor/html-scanner/html/node.rb +20 -1
  34. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +3 -0
  35. data/lib/action_controller/vendor/html-scanner/html/version.rb +1 -1
  36. data/lib/action_controller/vendor/xml_node.rb +97 -0
  37. data/lib/action_controller/verification.rb +2 -0
  38. data/lib/action_pack/version.rb +3 -3
  39. data/lib/action_view.rb +0 -2
  40. data/lib/action_view/base.rb +109 -36
  41. data/lib/action_view/compiled_templates.rb +1 -1
  42. data/lib/action_view/helpers/active_record_helper.rb +4 -2
  43. data/lib/action_view/helpers/asset_tag_helper.rb +6 -7
  44. data/lib/action_view/helpers/capture_helper.rb +49 -12
  45. data/lib/action_view/helpers/date_helper.rb +14 -4
  46. data/lib/action_view/helpers/form_helper.rb +136 -20
  47. data/lib/action_view/helpers/form_options_helper.rb +29 -7
  48. data/lib/action_view/helpers/form_tag_helper.rb +22 -20
  49. data/lib/action_view/helpers/java_script_macros_helper.rb +29 -9
  50. data/lib/action_view/helpers/javascript_helper.rb +50 -446
  51. data/lib/action_view/helpers/javascripts/controls.js +95 -30
  52. data/lib/action_view/helpers/javascripts/dragdrop.js +161 -21
  53. data/lib/action_view/helpers/javascripts/effects.js +310 -211
  54. data/lib/action_view/helpers/javascripts/prototype.js +228 -28
  55. data/lib/action_view/helpers/number_helper.rb +9 -9
  56. data/lib/action_view/helpers/pagination_helper.rb +1 -1
  57. data/lib/action_view/helpers/prototype_helper.rb +900 -0
  58. data/lib/action_view/helpers/scriptaculous_helper.rb +135 -0
  59. data/lib/action_view/helpers/text_helper.rb +7 -6
  60. data/lib/action_view/helpers/url_helper.rb +23 -14
  61. data/lib/action_view/partials.rb +12 -4
  62. data/rakefile +13 -5
  63. data/test/abstract_unit.rb +4 -3
  64. data/test/active_record_unit.rb +88 -0
  65. data/test/{controller → activerecord}/active_record_assertions_test.rb +7 -50
  66. data/test/{controller → activerecord}/active_record_store_test.rb +27 -4
  67. data/test/activerecord/pagination_test.rb +161 -0
  68. data/test/controller/action_pack_assertions_test.rb +18 -15
  69. data/test/controller/base_test.rb +31 -42
  70. data/test/controller/benchmark_test.rb +8 -11
  71. data/test/controller/capture_test.rb +33 -1
  72. data/test/controller/cgi_test.rb +33 -0
  73. data/test/controller/custom_handler_test.rb +8 -0
  74. data/test/controller/fake_controllers.rb +9 -17
  75. data/test/controller/filters_test.rb +32 -3
  76. data/test/controller/flash_test.rb +26 -41
  77. data/test/controller/fragment_store_setting_test.rb +1 -1
  78. data/test/controller/layout_test.rb +73 -0
  79. data/test/controller/mime_responds_test.rb +257 -0
  80. data/test/controller/mime_type_test.rb +24 -0
  81. data/test/controller/new_render_test.rb +157 -1
  82. data/test/controller/redirect_test.rb +23 -0
  83. data/test/controller/render_test.rb +54 -56
  84. data/test/controller/request_test.rb +25 -0
  85. data/test/controller/routing_test.rb +74 -66
  86. data/test/controller/test_test.rb +66 -1
  87. data/test/controller/verification_test.rb +3 -1
  88. data/test/controller/webservice_test.rb +255 -0
  89. data/test/fixtures/companies.yml +24 -0
  90. data/test/fixtures/company.rb +9 -0
  91. data/test/fixtures/db_definitions/sqlite.sql +42 -0
  92. data/test/fixtures/developer.rb +7 -0
  93. data/test/fixtures/developers.yml +21 -0
  94. data/test/fixtures/developers_projects.yml +13 -0
  95. data/test/fixtures/layout_tests/layouts/controller_name_space/nested.rhtml +1 -0
  96. data/test/fixtures/layout_tests/layouts/item.rhtml +1 -0
  97. data/test/fixtures/layout_tests/layouts/layout_test.rhtml +1 -0
  98. data/test/fixtures/layout_tests/layouts/third_party_template_library.mab +1 -0
  99. data/test/fixtures/layout_tests/views/hello.rhtml +1 -0
  100. data/test/fixtures/multipart/mona_lisa.jpg +0 -0
  101. data/test/fixtures/project.rb +3 -0
  102. data/test/fixtures/projects.yml +7 -0
  103. data/test/fixtures/replies.yml +13 -0
  104. data/test/fixtures/reply.rb +5 -0
  105. data/test/fixtures/respond_to/all_types_with_layout.rhtml +1 -0
  106. data/test/fixtures/respond_to/all_types_with_layout.rjs +1 -0
  107. data/test/fixtures/respond_to/layouts/standard.rhtml +1 -0
  108. data/test/fixtures/respond_to/using_defaults.rhtml +1 -0
  109. data/test/fixtures/respond_to/using_defaults.rjs +1 -0
  110. data/test/fixtures/respond_to/using_defaults.rxml +1 -0
  111. data/test/fixtures/respond_to/using_defaults_with_type_list.rhtml +1 -0
  112. data/test/fixtures/respond_to/using_defaults_with_type_list.rjs +1 -0
  113. data/test/fixtures/respond_to/using_defaults_with_type_list.rxml +1 -0
  114. data/test/fixtures/test/block_content_for.rhtml +2 -0
  115. data/test/fixtures/test/delete_with_js.rjs +2 -0
  116. data/test/fixtures/test/dot.directory/render_file_with_ivar.rhtml +1 -0
  117. data/test/fixtures/test/enum_rjs_test.rjs +6 -0
  118. data/test/fixtures/test/erb_content_for.rhtml +2 -0
  119. data/test/fixtures/test/hello_world.rxml +3 -0
  120. data/test/fixtures/test/hello_world_with_layout_false.rhtml +1 -0
  121. data/test/fixtures/test/non_erb_block_content_for.rxml +4 -0
  122. data/test/fixtures/topic.rb +3 -0
  123. data/test/fixtures/topics.yml +22 -0
  124. data/test/template/active_record_helper_test.rb +4 -0
  125. data/test/template/asset_tag_helper_test.rb +7 -2
  126. data/test/template/date_helper_test.rb +39 -2
  127. data/test/template/form_helper_test.rb +238 -5
  128. data/test/template/form_options_helper_test.rb +78 -0
  129. data/test/template/form_tag_helper_test.rb +11 -0
  130. data/test/template/java_script_macros_helper_test.rb +51 -6
  131. data/test/template/javascript_helper_test.rb +7 -153
  132. data/test/template/number_helper_test.rb +14 -13
  133. data/test/template/prototype_helper_test.rb +423 -0
  134. data/test/template/scriptaculous_helper_test.rb +90 -0
  135. data/test/template/text_helper_test.rb +12 -9
  136. data/test/template/url_helper_test.rb +31 -15
  137. metadata +291 -246
  138. data/lib/action_controller/cgi_ext/multipart_progress.rb +0 -169
  139. data/lib/action_controller/upload_progress.rb +0 -473
  140. data/lib/action_controller/vendor/html-scanner/html/node.rb.rej +0 -17
  141. data/lib/action_view/helpers/upload_progress_helper.rb +0 -433
  142. data/lib/action_view/vendor/builder.rb +0 -13
  143. data/lib/action_view/vendor/builder/blankslate.rb +0 -53
  144. data/lib/action_view/vendor/builder/xmlbase.rb +0 -143
  145. data/lib/action_view/vendor/builder/xmlevents.rb +0 -63
  146. data/lib/action_view/vendor/builder/xmlmarkup.rb +0 -308
  147. data/test/controller/multipart_progress_testx.rb +0 -365
  148. data/test/controller/upload_progress_testx.rb +0 -89
  149. data/test/template/upload_progress_helper_testx.rb +0 -136
@@ -6,8 +6,6 @@
6
6
  //
7
7
  // See scriptaculous.js for full license.
8
8
 
9
- /* ------------- element ext -------------- */
10
-
11
9
  // converts rgb() and #xxx to #xxxxxx format,
12
10
  // returns self (or first argument) if not convertable
13
11
  String.prototype.parseColor = function() {
@@ -22,33 +20,29 @@ String.prototype.parseColor = function() {
22
20
  }
23
21
  }
24
22
  return(color.length==7 ? color : (arguments[0] || this));
25
- }
23
+ }
26
24
 
27
- Element.collectTextNodesIgnoreClass = function(element, ignoreclass) {
28
- var children = $(element).childNodes;
29
- var text = '';
30
- var classtest = new RegExp('^([^ ]+ )*' + ignoreclass+ '( [^ ]+)*$','i');
31
-
32
- for (var i = 0; i < children.length; i++) {
33
- if(children[i].nodeType==3) {
34
- text+=children[i].nodeValue;
35
- } else {
36
- if((!children[i].className.match(classtest)) && children[i].hasChildNodes())
37
- text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass);
38
- }
39
- }
40
-
41
- return text;
25
+ /*--------------------------------------------------------------------------*/
26
+
27
+ Element.collectTextNodes = function(element) {
28
+ return $A($(element).childNodes).collect( function(node) {
29
+ return (node.nodeType==3 ? node.nodeValue :
30
+ (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
31
+ }).flatten().join('');
42
32
  }
43
33
 
44
- Element.setStyle = function(element, style) {
45
- element = $(element);
46
- for(k in style) element.style[k.camelize()] = style[k];
34
+ Element.collectTextNodesIgnoreClass = function(element, className) {
35
+ return $A($(element).childNodes).collect( function(node) {
36
+ return (node.nodeType==3 ? node.nodeValue :
37
+ ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
38
+ Element.collectTextNodesIgnoreClass(node, className) : ''));
39
+ }).flatten().join('');
47
40
  }
48
41
 
49
- Element.setContentZoom = function(element, percent) {
42
+ Element.setContentZoom = function(element, percent) {
43
+ element = $(element);
50
44
  Element.setStyle(element, {fontSize: (percent/100) + 'em'});
51
- if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
45
+ if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
52
46
  }
53
47
 
54
48
  Element.getOpacity = function(element){
@@ -75,18 +69,35 @@ Element.setOpacity = function(element, value){
75
69
  Element.setStyle(element,
76
70
  { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
77
71
  'alpha(opacity='+value*100+')' });
78
- }
72
+ }
79
73
  }
80
74
 
81
75
  Element.getInlineOpacity = function(element){
82
76
  return $(element).style.opacity || '';
83
77
  }
84
78
 
85
- Element.childrenWithClassName = function(element, className) {
86
- return $A($(element).getElementsByTagName('*')).select(
87
- function(c) { return Element.hasClassName(c, className) });
79
+ Element.childrenWithClassName = function(element, className, findFirst) {
80
+ return [$A($(element).getElementsByTagName('*'))[findFirst ? 'detect' : 'select']( function(c) {
81
+ return c.className ? Element.hasClassName(c, className) : false;
82
+ })].flatten();
88
83
  }
89
84
 
85
+ Element.forceRerendering = function(element) {
86
+ try {
87
+ element = $(element);
88
+ var n = document.createTextNode(' ');
89
+ element.appendChild(n);
90
+ element.removeChild(n);
91
+ } catch(e) { }
92
+ };
93
+
94
+ ['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom',
95
+ 'collectTextNodes','collectTextNodesIgnoreClass','childrenWithClassName'].each(
96
+ function(f) { Element.Methods[f] = Element[f]; }
97
+ );
98
+
99
+ /*--------------------------------------------------------------------------*/
100
+
90
101
  Array.prototype.call = function() {
91
102
  var args = arguments;
92
103
  this.each(function(f){ f.apply(this, args) });
@@ -129,6 +140,20 @@ var Effect = {
129
140
  $A(elements).each( function(element, index) {
130
141
  new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
131
142
  });
143
+ },
144
+ PAIRS: {
145
+ 'slide': ['SlideDown','SlideUp'],
146
+ 'blind': ['BlindDown','BlindUp'],
147
+ 'appear': ['Appear','Fade']
148
+ },
149
+ toggle: function(element, effect) {
150
+ element = $(element);
151
+ effect = (effect || 'appear').toLowerCase();
152
+ var options = Object.extend({
153
+ queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
154
+ }, arguments[2] || {});
155
+ Effect[element.visible() ?
156
+ Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
132
157
  }
133
158
  };
134
159
 
@@ -166,16 +191,22 @@ Effect.Transitions.full = function(pos) {
166
191
 
167
192
  /* ------------- core effects ------------- */
168
193
 
169
- Effect.Queue = {
170
- effects: [],
194
+ Effect.ScopedQueue = Class.create();
195
+ Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
196
+ initialize: function() {
197
+ this.effects = [];
198
+ this.interval = null;
199
+ },
171
200
  _each: function(iterator) {
172
201
  this.effects._each(iterator);
173
202
  },
174
- interval: null,
175
203
  add: function(effect) {
176
204
  var timestamp = new Date().getTime();
177
205
 
178
- switch(effect.options.queue) {
206
+ var position = (typeof effect.options.queue == 'string') ?
207
+ effect.options.queue : effect.options.queue.position;
208
+
209
+ switch(position) {
179
210
  case 'front':
180
211
  // move unstarted effects after this effect
181
212
  this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
@@ -191,7 +222,10 @@ Effect.Queue = {
191
222
 
192
223
  effect.startOn += timestamp;
193
224
  effect.finishOn += timestamp;
194
- this.effects.push(effect);
225
+
226
+ if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
227
+ this.effects.push(effect);
228
+
195
229
  if(!this.interval)
196
230
  this.interval = setInterval(this.loop.bind(this), 40);
197
231
  },
@@ -206,32 +240,45 @@ Effect.Queue = {
206
240
  var timePos = new Date().getTime();
207
241
  this.effects.invoke('loop', timePos);
208
242
  }
243
+ });
244
+
245
+ Effect.Queues = {
246
+ instances: $H(),
247
+ get: function(queueName) {
248
+ if(typeof queueName != 'string') return queueName;
249
+
250
+ if(!this.instances[queueName])
251
+ this.instances[queueName] = new Effect.ScopedQueue();
252
+
253
+ return this.instances[queueName];
254
+ }
255
+ }
256
+ Effect.Queue = Effect.Queues.get('global');
257
+
258
+ Effect.DefaultOptions = {
259
+ transition: Effect.Transitions.sinoidal,
260
+ duration: 1.0, // seconds
261
+ fps: 25.0, // max. 25fps due to Effect.Queue implementation
262
+ sync: false, // true for combining
263
+ from: 0.0,
264
+ to: 1.0,
265
+ delay: 0.0,
266
+ queue: 'parallel'
209
267
  }
210
- Object.extend(Effect.Queue, Enumerable);
211
268
 
212
269
  Effect.Base = function() {};
213
270
  Effect.Base.prototype = {
214
271
  position: null,
215
- setOptions: function(options) {
216
- this.options = Object.extend({
217
- transition: Effect.Transitions.sinoidal,
218
- duration: 1.0, // seconds
219
- fps: 25.0, // max. 25fps due to Effect.Queue implementation
220
- sync: false, // true for combining
221
- from: 0.0,
222
- to: 1.0,
223
- delay: 0.0,
224
- queue: 'parallel'
225
- }, options || {});
226
- },
227
272
  start: function(options) {
228
- this.setOptions(options || {});
273
+ this.options = Object.extend(Object.extend({},Effect.DefaultOptions), options || {});
229
274
  this.currentFrame = 0;
230
275
  this.state = 'idle';
231
276
  this.startOn = this.options.delay*1000;
232
277
  this.finishOn = this.startOn + (this.options.duration*1000);
233
278
  this.event('beforeStart');
234
- if(!this.options.sync) Effect.Queue.add(this);
279
+ if(!this.options.sync)
280
+ Effect.Queues.get(typeof this.options.queue == 'string' ?
281
+ 'global' : this.options.queue.scope).add(this);
235
282
  },
236
283
  loop: function(timePos) {
237
284
  if(timePos >= this.startOn) {
@@ -269,7 +316,9 @@ Effect.Base.prototype = {
269
316
  }
270
317
  },
271
318
  cancel: function() {
272
- if(!this.options.sync) Effect.Queue.remove(this);
319
+ if(!this.options.sync)
320
+ Effect.Queues.get(typeof this.options.queue == 'string' ?
321
+ 'global' : this.options.queue.scope).remove(this);
273
322
  this.state = 'finished';
274
323
  },
275
324
  event: function(eventName) {
@@ -307,43 +356,57 @@ Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
307
356
  this.element = $(element);
308
357
  // make this work on IE on elements without 'layout'
309
358
  if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout))
310
- Element.setStyle(this.element, {zoom: 1});
359
+ this.element.setStyle({zoom: 1});
311
360
  var options = Object.extend({
312
- from: Element.getOpacity(this.element) || 0.0,
361
+ from: this.element.getOpacity() || 0.0,
313
362
  to: 1.0
314
363
  }, arguments[1] || {});
315
364
  this.start(options);
316
365
  },
317
366
  update: function(position) {
318
- Element.setOpacity(this.element, position);
367
+ this.element.setOpacity(position);
319
368
  }
320
369
  });
321
370
 
322
- Effect.MoveBy = Class.create();
323
- Object.extend(Object.extend(Effect.MoveBy.prototype, Effect.Base.prototype), {
324
- initialize: function(element, toTop, toLeft) {
325
- this.element = $(element);
326
- this.toTop = toTop;
327
- this.toLeft = toLeft;
328
- this.start(arguments[3]);
371
+ Effect.Move = Class.create();
372
+ Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
373
+ initialize: function(element) {
374
+ this.element = $(element);
375
+ var options = Object.extend({
376
+ x: 0,
377
+ y: 0,
378
+ mode: 'relative'
379
+ }, arguments[1] || {});
380
+ this.start(options);
329
381
  },
330
382
  setup: function() {
331
383
  // Bug in Opera: Opera returns the "real" position of a static element or
332
384
  // relative element that does not have top/left explicitly set.
333
385
  // ==> Always set top and left for position relative elements in your stylesheets
334
386
  // (to 0 if you do not need them)
335
- Element.makePositioned(this.element);
336
- this.originalTop = parseFloat(Element.getStyle(this.element,'top') || '0');
337
- this.originalLeft = parseFloat(Element.getStyle(this.element,'left') || '0');
387
+ this.element.makePositioned();
388
+ this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
389
+ this.originalTop = parseFloat(this.element.getStyle('top') || '0');
390
+ if(this.options.mode == 'absolute') {
391
+ // absolute movement, so we need to calc deltaX and deltaY
392
+ this.options.x = this.options.x - this.originalLeft;
393
+ this.options.y = this.options.y - this.originalTop;
394
+ }
338
395
  },
339
396
  update: function(position) {
340
- Element.setStyle(this.element, {
341
- top: this.toTop * position + this.originalTop + 'px',
342
- left: this.toLeft * position + this.originalLeft + 'px'
397
+ this.element.setStyle({
398
+ left: this.options.x * position + this.originalLeft + 'px',
399
+ top: this.options.y * position + this.originalTop + 'px'
343
400
  });
344
401
  }
345
402
  });
346
403
 
404
+ // for backwards compatibility
405
+ Effect.MoveBy = function(element, toTop, toLeft) {
406
+ return new Effect.Move(element,
407
+ Object.extend({ x: toLeft, y: toTop }, arguments[3] || {}));
408
+ };
409
+
347
410
  Effect.Scale = Class.create();
348
411
  Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
349
412
  initialize: function(element, percent) {
@@ -361,7 +424,7 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
361
424
  },
362
425
  setup: function() {
363
426
  this.restoreAfterFinish = this.options.restoreAfterFinish || false;
364
- this.elementPositioning = Element.getStyle(this.element,'position');
427
+ this.elementPositioning = this.element.getStyle('position');
365
428
 
366
429
  this.originalStyle = {};
367
430
  ['top','left','width','height','fontSize'].each( function(k) {
@@ -371,7 +434,7 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
371
434
  this.originalTop = this.element.offsetTop;
372
435
  this.originalLeft = this.element.offsetLeft;
373
436
 
374
- var fontSize = Element.getStyle(this.element,'font-size') || '100%';
437
+ var fontSize = this.element.getStyle('font-size') || '100%';
375
438
  ['em','px','%'].each( function(fontSizeType) {
376
439
  if(fontSize.indexOf(fontSizeType)>0) {
377
440
  this.fontSize = parseFloat(fontSize);
@@ -393,11 +456,11 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
393
456
  update: function(position) {
394
457
  var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
395
458
  if(this.options.scaleContent && this.fontSize)
396
- Element.setStyle(this.element, {fontSize: this.fontSize * currentScale + this.fontSizeType });
459
+ this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
397
460
  this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
398
461
  },
399
462
  finish: function(position) {
400
- if (this.restoreAfterFinish) Element.setStyle(this.element, this.originalStyle);
463
+ if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
401
464
  },
402
465
  setDimensions: function(height, width) {
403
466
  var d = {};
@@ -414,7 +477,7 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
414
477
  if(this.options.scaleX) d.left = -leftd + 'px';
415
478
  }
416
479
  }
417
- Element.setStyle(this.element, d);
480
+ this.element.setStyle(d);
418
481
  }
419
482
  });
420
483
 
@@ -427,25 +490,25 @@ Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype),
427
490
  },
428
491
  setup: function() {
429
492
  // Prevent executing on elements not in the layout flow
430
- if(Element.getStyle(this.element, 'display')=='none') { this.cancel(); return; }
493
+ if(this.element.getStyle('display')=='none') { this.cancel(); return; }
431
494
  // Disable background image during the effect
432
495
  this.oldStyle = {
433
- backgroundImage: Element.getStyle(this.element, 'background-image') };
434
- Element.setStyle(this.element, {backgroundImage: 'none'});
496
+ backgroundImage: this.element.getStyle('background-image') };
497
+ this.element.setStyle({backgroundImage: 'none'});
435
498
  if(!this.options.endcolor)
436
- this.options.endcolor = Element.getStyle(this.element, 'background-color').parseColor('#ffffff');
499
+ this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
437
500
  if(!this.options.restorecolor)
438
- this.options.restorecolor = Element.getStyle(this.element, 'background-color');
501
+ this.options.restorecolor = this.element.getStyle('background-color');
439
502
  // init color calculations
440
503
  this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
441
504
  this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
442
505
  },
443
506
  update: function(position) {
444
- Element.setStyle(this.element,{backgroundColor: $R(0,2).inject('#',function(m,v,i){
507
+ this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
445
508
  return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) });
446
509
  },
447
510
  finish: function() {
448
- Element.setStyle(this.element, Object.extend(this.oldStyle, {
511
+ this.element.setStyle(Object.extend(this.oldStyle, {
449
512
  backgroundColor: this.options.restorecolor
450
513
  }));
451
514
  }
@@ -479,85 +542,91 @@ Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
479
542
  /* ------------- combination effects ------------- */
480
543
 
481
544
  Effect.Fade = function(element) {
482
- var oldOpacity = Element.getInlineOpacity(element);
545
+ element = $(element);
546
+ var oldOpacity = element.getInlineOpacity();
483
547
  var options = Object.extend({
484
- from: Element.getOpacity(element) || 1.0,
548
+ from: element.getOpacity() || 1.0,
485
549
  to: 0.0,
486
- afterFinishInternal: function(effect) { with(Element) {
550
+ afterFinishInternal: function(effect) {
487
551
  if(effect.options.to!=0) return;
488
- hide(effect.element);
489
- setStyle(effect.element, {opacity: oldOpacity}); }}
490
- }, arguments[1] || {});
552
+ effect.element.hide();
553
+ effect.element.setStyle({opacity: oldOpacity});
554
+ }}, arguments[1] || {});
491
555
  return new Effect.Opacity(element,options);
492
556
  }
493
557
 
494
558
  Effect.Appear = function(element) {
559
+ element = $(element);
495
560
  var options = Object.extend({
496
- from: (Element.getStyle(element, 'display') == 'none' ? 0.0 : Element.getOpacity(element) || 0.0),
561
+ from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
497
562
  to: 1.0,
498
- beforeSetup: function(effect) { with(Element) {
499
- setOpacity(effect.element, effect.options.from);
500
- show(effect.element); }}
501
- }, arguments[1] || {});
563
+ // force Safari to render floated elements properly
564
+ afterFinishInternal: function(effect) {
565
+ effect.element.forceRerendering();
566
+ },
567
+ beforeSetup: function(effect) {
568
+ effect.element.setOpacity(effect.options.from);
569
+ effect.element.show();
570
+ }}, arguments[1] || {});
502
571
  return new Effect.Opacity(element,options);
503
572
  }
504
573
 
505
574
  Effect.Puff = function(element) {
506
575
  element = $(element);
507
- var oldStyle = { opacity: Element.getInlineOpacity(element), position: Element.getStyle(element, 'position') };
576
+ var oldStyle = { opacity: element.getInlineOpacity(), position: element.getStyle('position') };
508
577
  return new Effect.Parallel(
509
578
  [ new Effect.Scale(element, 200,
510
579
  { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
511
580
  new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
512
581
  Object.extend({ duration: 1.0,
513
- beforeSetupInternal: function(effect) { with(Element) {
514
- setStyle(effect.effects[0].element, {position: 'absolute'}); }},
515
- afterFinishInternal: function(effect) { with(Element) {
516
- hide(effect.effects[0].element);
517
- setStyle(effect.effects[0].element, oldStyle); }}
582
+ beforeSetupInternal: function(effect) {
583
+ effect.effects[0].element.setStyle({position: 'absolute'}); },
584
+ afterFinishInternal: function(effect) {
585
+ effect.effects[0].element.hide();
586
+ effect.effects[0].element.setStyle(oldStyle); }
518
587
  }, arguments[1] || {})
519
588
  );
520
589
  }
521
590
 
522
591
  Effect.BlindUp = function(element) {
523
592
  element = $(element);
524
- Element.makeClipping(element);
593
+ element.makeClipping();
525
594
  return new Effect.Scale(element, 0,
526
595
  Object.extend({ scaleContent: false,
527
596
  scaleX: false,
528
597
  restoreAfterFinish: true,
529
- afterFinishInternal: function(effect) { with(Element) {
530
- [hide, undoClipping].call(effect.element); }}
598
+ afterFinishInternal: function(effect) {
599
+ effect.element.hide();
600
+ effect.element.undoClipping();
601
+ }
531
602
  }, arguments[1] || {})
532
603
  );
533
604
  }
534
605
 
535
606
  Effect.BlindDown = function(element) {
536
607
  element = $(element);
537
- var oldHeight = Element.getStyle(element, 'height');
538
- var elementDimensions = Element.getDimensions(element);
608
+ var elementDimensions = element.getDimensions();
539
609
  return new Effect.Scale(element, 100,
540
610
  Object.extend({ scaleContent: false,
541
611
  scaleX: false,
542
612
  scaleFrom: 0,
543
613
  scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
544
614
  restoreAfterFinish: true,
545
- afterSetup: function(effect) { with(Element) {
546
- makeClipping(effect.element);
547
- setStyle(effect.element, {height: '0px'});
548
- show(effect.element);
549
- }},
550
- afterFinishInternal: function(effect) { with(Element) {
551
- undoClipping(effect.element);
552
- setStyle(effect.element, {height: oldHeight});
553
- }}
615
+ afterSetup: function(effect) {
616
+ effect.element.makeClipping();
617
+ effect.element.setStyle({height: '0px'});
618
+ effect.element.show();
619
+ },
620
+ afterFinishInternal: function(effect) {
621
+ effect.element.undoClipping();
622
+ }
554
623
  }, arguments[1] || {})
555
624
  );
556
625
  }
557
626
 
558
627
  Effect.SwitchOff = function(element) {
559
628
  element = $(element);
560
- var oldOpacity = Element.getInlineOpacity(element);
629
+ var oldOpacity = element.getInlineOpacity();
561
630
  return new Effect.Appear(element, {
562
631
  duration: 0.4,
563
632
  from: 0,
@@ -566,13 +635,16 @@ Effect.SwitchOff = function(element) {
566
635
  new Effect.Scale(effect.element, 1, {
567
636
  duration: 0.3, scaleFromCenter: true,
568
637
  scaleX: false, scaleContent: false, restoreAfterFinish: true,
569
- beforeSetup: function(effect) { with(Element) {
570
- [makePositioned,makeClipping].call(effect.element);
571
- }},
572
- afterFinishInternal: function(effect) { with(Element) {
573
- [hide,undoClipping,undoPositioned].call(effect.element);
574
- setStyle(effect.element, {opacity: oldOpacity});
575
- }}
638
+ beforeSetup: function(effect) {
639
+ effect.element.makePositioned();
640
+ effect.element.makeClipping();
641
+ },
642
+ afterFinishInternal: function(effect) {
643
+ effect.element.hide();
644
+ effect.element.undoClipping();
645
+ effect.element.undoPositioned();
646
+ effect.element.setStyle({opacity: oldOpacity});
647
+ }
576
648
  })
577
649
  }
578
650
  });
@@ -581,99 +653,110 @@ Effect.SwitchOff = function(element) {
581
653
  Effect.DropOut = function(element) {
582
654
  element = $(element);
583
655
  var oldStyle = {
584
- top: Element.getStyle(element, 'top'),
585
- left: Element.getStyle(element, 'left'),
586
- opacity: Element.getInlineOpacity(element) };
656
+ top: element.getStyle('top'),
657
+ left: element.getStyle('left'),
658
+ opacity: element.getInlineOpacity() };
587
659
  return new Effect.Parallel(
588
- [ new Effect.MoveBy(element, 100, 0, { sync: true }),
660
+ [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
589
661
  new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
590
662
  Object.extend(
591
663
  { duration: 0.5,
592
- beforeSetup: function(effect) { with(Element) {
593
- makePositioned(effect.effects[0].element); }},
594
- afterFinishInternal: function(effect) { with(Element) {
595
- [hide, undoPositioned].call(effect.effects[0].element);
596
- setStyle(effect.effects[0].element, oldStyle); }}
664
+ beforeSetup: function(effect) {
665
+ effect.effects[0].element.makePositioned();
666
+ },
667
+ afterFinishInternal: function(effect) {
668
+ effect.effects[0].element.hide();
669
+ effect.effects[0].element.undoPositioned();
670
+ effect.effects[0].element.setStyle(oldStyle);
671
+ }
597
672
  }, arguments[1] || {}));
598
673
  }
599
674
 
600
675
  Effect.Shake = function(element) {
601
676
  element = $(element);
602
677
  var oldStyle = {
603
- top: Element.getStyle(element, 'top'),
604
- left: Element.getStyle(element, 'left') };
605
- return new Effect.MoveBy(element, 0, 20,
606
- { duration: 0.05, afterFinishInternal: function(effect) {
607
- new Effect.MoveBy(effect.element, 0, -40,
608
- { duration: 0.1, afterFinishInternal: function(effect) {
609
- new Effect.MoveBy(effect.element, 0, 40,
610
- { duration: 0.1, afterFinishInternal: function(effect) {
611
- new Effect.MoveBy(effect.element, 0, -40,
612
- { duration: 0.1, afterFinishInternal: function(effect) {
613
- new Effect.MoveBy(effect.element, 0, 40,
614
- { duration: 0.1, afterFinishInternal: function(effect) {
615
- new Effect.MoveBy(effect.element, 0, -20,
616
- { duration: 0.05, afterFinishInternal: function(effect) { with(Element) {
617
- undoPositioned(effect.element);
618
- setStyle(effect.element, oldStyle);
619
- }}}) }}) }}) }}) }}) }});
678
+ top: element.getStyle('top'),
679
+ left: element.getStyle('left') };
680
+ return new Effect.Move(element,
681
+ { x: 20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
682
+ new Effect.Move(effect.element,
683
+ { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
684
+ new Effect.Move(effect.element,
685
+ { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
686
+ new Effect.Move(effect.element,
687
+ { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
688
+ new Effect.Move(effect.element,
689
+ { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
690
+ new Effect.Move(effect.element,
691
+ { x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
692
+ effect.element.undoPositioned();
693
+ effect.element.setStyle(oldStyle);
694
+ }}) }}) }}) }}) }}) }});
620
695
  }
621
696
 
622
697
  Effect.SlideDown = function(element) {
623
698
  element = $(element);
624
- Element.cleanWhitespace(element);
699
+ element.cleanWhitespace();
625
700
  // SlideDown need to have the content of the element wrapped in a container element with fixed height!
626
- var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom');
627
- var elementDimensions = Element.getDimensions(element);
701
+ var oldInnerBottom = $(element.firstChild).getStyle('bottom');
702
+ var elementDimensions = element.getDimensions();
628
703
  return new Effect.Scale(element, 100, Object.extend({
629
704
  scaleContent: false,
630
705
  scaleX: false,
631
706
  scaleFrom: 0,
632
707
  scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
633
708
  restoreAfterFinish: true,
634
- afterSetup: function(effect) { with(Element) {
635
- makePositioned(effect.element);
636
- makePositioned(effect.element.firstChild);
637
- if(window.opera) setStyle(effect.element, {top: ''});
638
- makeClipping(effect.element);
639
- setStyle(effect.element, {height: '0px'});
640
- show(element); }},
641
- afterUpdateInternal: function(effect) { with(Element) {
642
- setStyle(effect.element.firstChild, {bottom:
643
- (effect.dims[0] - effect.element.clientHeight) + 'px' }); }},
644
- afterFinishInternal: function(effect) { with(Element) {
645
- undoClipping(effect.element);
646
- undoPositioned(effect.element.firstChild);
647
- undoPositioned(effect.element);
648
- setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }}
709
+ afterSetup: function(effect) {
710
+ effect.element.makePositioned();
711
+ effect.element.firstChild.makePositioned();
712
+ if(window.opera) effect.element.setStyle({top: ''});
713
+ effect.element.makeClipping();
714
+ effect.element.setStyle({height: '0px'});
715
+ effect.element.show(); },
716
+ afterUpdateInternal: function(effect) {
717
+ effect.element.firstChild.setStyle({bottom:
718
+ (effect.dims[0] - effect.element.clientHeight) + 'px' });
719
+ },
720
+ afterFinishInternal: function(effect) {
721
+ effect.element.undoClipping();
722
+ // IE will crash if child is undoPositioned first
723
+ if(/MSIE/.test(navigator.userAgent)){
724
+ effect.element.undoPositioned();
725
+ effect.element.firstChild.undoPositioned();
726
+ }else{
727
+ effect.element.firstChild.undoPositioned();
728
+ effect.element.undoPositioned();
729
+ }
730
+ effect.element.firstChild.setStyle({bottom: oldInnerBottom}); }
649
731
  }, arguments[1] || {})
650
732
  );
651
733
  }
652
734
 
653
735
  Effect.SlideUp = function(element) {
654
736
  element = $(element);
655
- Element.cleanWhitespace(element);
656
- var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom');
737
+ element.cleanWhitespace();
738
+ var oldInnerBottom = $(element.firstChild).getStyle('bottom');
657
739
  return new Effect.Scale(element, 0,
658
740
  Object.extend({ scaleContent: false,
659
741
  scaleX: false,
660
742
  scaleMode: 'box',
661
743
  scaleFrom: 100,
662
744
  restoreAfterFinish: true,
663
- beforeStartInternal: function(effect) { with(Element) {
664
- makePositioned(effect.element);
665
- makePositioned(effect.element.firstChild);
666
- if(window.opera) setStyle(effect.element, {top: ''});
667
- makeClipping(effect.element);
668
- show(element); }},
669
- afterUpdateInternal: function(effect) { with(Element) {
670
- setStyle(effect.element.firstChild, {bottom:
671
- (effect.dims[0] - effect.element.clientHeight) + 'px' }); }},
672
- afterFinishInternal: function(effect) { with(Element) {
673
- [hide, undoClipping].call(effect.element);
674
- undoPositioned(effect.element.firstChild);
675
- undoPositioned(effect.element);
676
- setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }}
745
+ beforeStartInternal: function(effect) {
746
+ effect.element.makePositioned();
747
+ effect.element.firstChild.makePositioned();
748
+ if(window.opera) effect.element.setStyle({top: ''});
749
+ effect.element.makeClipping();
750
+ effect.element.show(); },
751
+ afterUpdateInternal: function(effect) {
752
+ effect.element.firstChild.setStyle({bottom:
753
+ (effect.dims[0] - effect.element.clientHeight) + 'px' }); },
754
+ afterFinishInternal: function(effect) {
755
+ effect.element.hide();
756
+ effect.element.undoClipping();
757
+ effect.element.firstChild.undoPositioned();
758
+ effect.element.undoPositioned();
759
+ effect.element.setStyle({bottom: oldInnerBottom}); }
677
760
  }, arguments[1] || {})
678
761
  );
679
762
  }
@@ -682,11 +765,11 @@ Effect.SlideUp = function(element) {
682
765
  Effect.Squish = function(element) {
683
766
  return new Effect.Scale(element, window.opera ? 1 : 0,
684
767
  { restoreAfterFinish: true,
685
- beforeSetup: function(effect) { with(Element) {
686
- makeClipping(effect.element); }},
687
- afterFinishInternal: function(effect) { with(Element) {
688
- hide(effect.element);
689
- undoClipping(effect.element); }}
768
+ beforeSetup: function(effect) {
769
+ effect.element.makeClipping(effect.element); },
770
+ afterFinishInternal: function(effect) {
771
+ effect.element.hide(effect.element);
772
+ effect.element.undoClipping(effect.element); }
690
773
  });
691
774
  }
692
775
 
@@ -694,7 +777,7 @@ Effect.Grow = function(element) {
694
777
  element = $(element);
695
778
  var options = Object.extend({
696
779
  direction: 'center',
697
- moveTransistion: Effect.Transitions.sinoidal,
780
+ moveTransition: Effect.Transitions.sinoidal,
698
781
  scaleTransition: Effect.Transitions.sinoidal,
699
782
  opacityTransition: Effect.Transitions.full
700
783
  }, arguments[1] || {});
@@ -703,9 +786,9 @@ Effect.Grow = function(element) {
703
786
  left: element.style.left,
704
787
  height: element.style.height,
705
788
  width: element.style.width,
706
- opacity: Element.getInlineOpacity(element) };
789
+ opacity: element.getInlineOpacity() };
707
790
 
708
- var dims = Element.getDimensions(element);
791
+ var dims = element.getDimensions();
709
792
  var initialMoveX, initialMoveY;
710
793
  var moveX, moveY;
711
794
 
@@ -737,27 +820,32 @@ Effect.Grow = function(element) {
737
820
  break;
738
821
  }
739
822
 
740
- return new Effect.MoveBy(element, initialMoveY, initialMoveX, {
823
+ return new Effect.Move(element, {
824
+ x: initialMoveX,
825
+ y: initialMoveY,
741
826
  duration: 0.01,
742
- beforeSetup: function(effect) { with(Element) {
743
- hide(effect.element);
744
- makeClipping(effect.element);
745
- makePositioned(effect.element);
746
- }},
827
+ beforeSetup: function(effect) {
828
+ effect.element.hide();
829
+ effect.element.makeClipping();
830
+ effect.element.makePositioned();
831
+ },
747
832
  afterFinishInternal: function(effect) {
748
833
  new Effect.Parallel(
749
834
  [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
750
- new Effect.MoveBy(effect.element, moveY, moveX, { sync: true, transition: options.moveTransition }),
835
+ new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
751
836
  new Effect.Scale(effect.element, 100, {
752
837
  scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
753
838
  sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
754
839
  ], Object.extend({
755
- beforeSetup: function(effect) { with(Element) {
756
- setStyle(effect.effects[0].element, {height: '0px'});
757
- show(effect.effects[0].element); }},
758
- afterFinishInternal: function(effect) { with(Element) {
759
- [undoClipping, undoPositioned].call(effect.effects[0].element);
760
- setStyle(effect.effects[0].element, oldStyle); }}
840
+ beforeSetup: function(effect) {
841
+ effect.effects[0].element.setStyle({height: '0px'});
842
+ effect.effects[0].element.show();
843
+ },
844
+ afterFinishInternal: function(effect) {
845
+ effect.effects[0].element.undoClipping();
846
+ effect.effects[0].element.undoPositioned();
847
+ effect.effects[0].element.setStyle(oldStyle);
848
+ }
761
849
  }, options)
762
850
  )
763
851
  }
@@ -768,7 +856,7 @@ Effect.Shrink = function(element) {
768
856
  element = $(element);
769
857
  var options = Object.extend({
770
858
  direction: 'center',
771
- moveTransistion: Effect.Transitions.sinoidal,
859
+ moveTransition: Effect.Transitions.sinoidal,
772
860
  scaleTransition: Effect.Transitions.sinoidal,
773
861
  opacityTransition: Effect.Transitions.none
774
862
  }, arguments[1] || {});
@@ -777,9 +865,9 @@ Effect.Shrink = function(element) {
777
865
  left: element.style.left,
778
866
  height: element.style.height,
779
867
  width: element.style.width,
780
- opacity: Element.getInlineOpacity(element) };
868
+ opacity: element.getInlineOpacity() };
781
869
 
782
- var dims = Element.getDimensions(element);
870
+ var dims = element.getDimensions();
783
871
  var moveX, moveY;
784
872
 
785
873
  switch (options.direction) {
@@ -807,13 +895,16 @@ Effect.Shrink = function(element) {
807
895
  return new Effect.Parallel(
808
896
  [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
809
897
  new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
810
- new Effect.MoveBy(element, moveY, moveX, { sync: true, transition: options.moveTransition })
898
+ new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
811
899
  ], Object.extend({
812
- beforeStartInternal: function(effect) { with(Element) {
813
- [makePositioned, makeClipping].call(effect.effects[0].element) }},
814
- afterFinishInternal: function(effect) { with(Element) {
815
- [hide, undoClipping, undoPositioned].call(effect.effects[0].element);
816
- setStyle(effect.effects[0].element, oldStyle); }}
900
+ beforeStartInternal: function(effect) {
901
+ effect.effects[0].element.makePositioned();
902
+ effect.effects[0].element.makeClipping(); },
903
+ afterFinishInternal: function(effect) {
904
+ effect.effects[0].element.hide();
905
+ effect.effects[0].element.undoClipping();
906
+ effect.effects[0].element.undoPositioned();
907
+ effect.effects[0].element.setStyle(oldStyle); }
817
908
  }, options)
818
909
  );
819
910
  }
@@ -821,13 +912,13 @@ Effect.Shrink = function(element) {
821
912
  Effect.Pulsate = function(element) {
822
913
  element = $(element);
823
914
  var options = arguments[1] || {};
824
- var oldOpacity = Element.getInlineOpacity(element);
915
+ var oldOpacity = element.getInlineOpacity();
825
916
  var transition = options.transition || Effect.Transitions.sinoidal;
826
917
  var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) };
827
918
  reverser.bind(transition);
828
919
  return new Effect.Opacity(element,
829
920
  Object.extend(Object.extend({ duration: 3.0, from: 0,
830
- afterFinishInternal: function(effect) { Element.setStyle(effect.element, {opacity: oldOpacity}); }
921
+ afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
831
922
  }, options), {transition: reverser}));
832
923
  }
833
924
 
@@ -846,9 +937,17 @@ Effect.Fold = function(element) {
846
937
  new Effect.Scale(element, 1, {
847
938
  scaleContent: false,
848
939
  scaleY: false,
849
- afterFinishInternal: function(effect) { with(Element) {
850
- [hide, undoClipping].call(effect.element);
851
- setStyle(effect.element, oldStyle);
852
- }} });
940
+ afterFinishInternal: function(effect) {
941
+ effect.element.hide();
942
+ effect.element.undoClipping();
943
+ effect.element.setStyle(oldStyle);
944
+ } });
853
945
  }}, arguments[1] || {}));
854
946
  }
947
+
948
+ Element.Methods.visualEffect = function(element, effect, options) {
949
+ s = effect.gsub(/_/, '-').camelize();
950
+ effect_class = s.charAt(0).toUpperCase() + s.substring(1);
951
+ new Effect[effect_class](element, options);
952
+ return $(element);
953
+ };