merb 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. data/README +64 -80
  2. data/Rakefile +25 -12
  3. data/bin/merb +2 -223
  4. data/examples/README_EXAMPLES +10 -0
  5. data/examples/skeleton.tar +0 -0
  6. data/lib/merb.rb +48 -21
  7. data/lib/merb/core_ext.rb +12 -2
  8. data/lib/merb/core_ext/merb_class.rb +21 -21
  9. data/lib/merb/core_ext/merb_kernel.rb +60 -0
  10. data/lib/merb/core_ext/merb_object.rb +14 -0
  11. data/lib/merb/core_ext/merb_string.rb +3 -13
  12. data/lib/merb/generators/merb_app/merb_app.rb +33 -0
  13. data/lib/merb/merb_constants.rb +7 -0
  14. data/lib/merb/merb_controller.rb +31 -23
  15. data/lib/merb/merb_drb_server.rb +6 -60
  16. data/lib/merb/merb_exceptions.rb +162 -2
  17. data/lib/merb/merb_handler.rb +8 -19
  18. data/lib/merb/merb_mailer.rb +60 -0
  19. data/lib/merb/merb_router.rb +1 -1
  20. data/lib/merb/merb_server.rb +240 -0
  21. data/lib/merb/merb_upload_handler.rb +1 -1
  22. data/lib/merb/merb_view_context.rb +11 -6
  23. data/lib/merb/mixins/basic_authentication_mixin.rb +11 -13
  24. data/lib/merb/mixins/controller_mixin.rb +12 -6
  25. data/lib/merb/mixins/form_control_mixin.rb +94 -0
  26. data/lib/merb/mixins/render_mixin.rb +50 -24
  27. data/lib/merb/mixins/view_context_mixin.rb +122 -0
  28. data/lib/merb/session/merb_ar_session.rb +13 -14
  29. data/lib/merb/session/merb_memory_session.rb +105 -0
  30. metadata +13 -132
  31. data/examples/app_skeleton/Rakefile +0 -82
  32. data/examples/app_skeleton/dist/app/helpers/global_helper.rb +0 -6
  33. data/examples/app_skeleton/dist/conf/merb.yml +0 -11
  34. data/examples/app_skeleton/dist/conf/merb_init.rb +0 -16
  35. data/examples/app_skeleton/dist/conf/mup.conf +0 -5
  36. data/examples/app_skeleton/dist/conf/router.rb +0 -19
  37. data/examples/app_skeleton/scripts/merb_stop +0 -13
  38. data/examples/app_skeleton/scripts/new_migration +0 -21
  39. data/examples/app_skeleton/test/test_helper.rb +0 -1
  40. data/examples/sample_app/Rakefile +0 -82
  41. data/examples/sample_app/dist/app/controllers/files.rb +0 -31
  42. data/examples/sample_app/dist/app/controllers/posts.rb +0 -71
  43. data/examples/sample_app/dist/app/controllers/test.rb +0 -40
  44. data/examples/sample_app/dist/app/helpers/global_helper.rb +0 -7
  45. data/examples/sample_app/dist/app/helpers/posts_helper.rb +0 -4
  46. data/examples/sample_app/dist/app/models/comment.rb +0 -3
  47. data/examples/sample_app/dist/app/models/post.rb +0 -4
  48. data/examples/sample_app/dist/app/views/files/progress.jerb +0 -3
  49. data/examples/sample_app/dist/app/views/files/start.herb +0 -62
  50. data/examples/sample_app/dist/app/views/files/upload.herb +0 -6
  51. data/examples/sample_app/dist/app/views/layout/application.herb +0 -61
  52. data/examples/sample_app/dist/app/views/layout/foo.herb +0 -6
  53. data/examples/sample_app/dist/app/views/posts/_comments.herb +0 -11
  54. data/examples/sample_app/dist/app/views/posts/comment.jerb +0 -1
  55. data/examples/sample_app/dist/app/views/posts/list.herb +0 -5
  56. data/examples/sample_app/dist/app/views/posts/new.herb +0 -37
  57. data/examples/sample_app/dist/app/views/posts/show.herb +0 -37
  58. data/examples/sample_app/dist/app/views/posts/xml_test.xerb +0 -3
  59. data/examples/sample_app/dist/app/views/shared/_test.herb +0 -1
  60. data/examples/sample_app/dist/app/views/test/foo.herb +0 -2
  61. data/examples/sample_app/dist/app/views/test/hello.herb +0 -5
  62. data/examples/sample_app/dist/app/views/test/json.jerb +0 -1
  63. data/examples/sample_app/dist/conf/merb.yml +0 -11
  64. data/examples/sample_app/dist/conf/merb_init.rb +0 -24
  65. data/examples/sample_app/dist/conf/mup.conf +0 -5
  66. data/examples/sample_app/dist/conf/router.rb +0 -19
  67. data/examples/sample_app/dist/public/images/bg.jpg +0 -0
  68. data/examples/sample_app/dist/public/images/book.gif +0 -0
  69. data/examples/sample_app/dist/public/images/booksmall.gif +0 -0
  70. data/examples/sample_app/dist/public/images/greenright.jpg +0 -0
  71. data/examples/sample_app/dist/public/images/louiecon.gif +0 -0
  72. data/examples/sample_app/dist/public/images/menu.gif +0 -0
  73. data/examples/sample_app/dist/public/images/menuleft.gif +0 -0
  74. data/examples/sample_app/dist/public/images/menuright.gif +0 -0
  75. data/examples/sample_app/dist/public/images/mountain.jpg +0 -0
  76. data/examples/sample_app/dist/public/images/n3.jpg +0 -0
  77. data/examples/sample_app/dist/public/images/nautica.jpg +0 -0
  78. data/examples/sample_app/dist/public/javascripts/application.js +0 -0
  79. data/examples/sample_app/dist/public/javascripts/effects.js +0 -975
  80. data/examples/sample_app/dist/public/javascripts/mup.js +0 -113
  81. data/examples/sample_app/dist/public/javascripts/prototype.js +0 -2264
  82. data/examples/sample_app/dist/public/stylesheets/merb.css +0 -277
  83. data/examples/sample_app/dist/public/test.html +0 -5
  84. data/examples/sample_app/dist/schema/migrations/001_add_comments_to_posts.rb +0 -22
  85. data/examples/sample_app/dist/schema/migrations/002_add_sessions_table.rb +0 -14
  86. data/examples/sample_app/dist/schema/schema.rb +0 -28
  87. data/examples/sample_app/foo.txt +0 -0
  88. data/examples/sample_app/log/merb.4000.pid +0 -1
  89. data/examples/sample_app/script/merb_stop +0 -13
  90. data/examples/sample_app/script/new_migration +0 -21
  91. data/examples/sample_app/test/test_helper.rb +0 -1
  92. data/lib/merb/mixins/javascript_mixin.rb +0 -147
  93. data/lib/merb/session/merb_drb_session.rb +0 -65
  94. data/test/test_helper.rb +0 -1
  95. data/test/unit/route_matcher_test.rb +0 -46
@@ -1,6 +0,0 @@
1
- <html>
2
- <title>Foo.rhtml</title>
3
- <body>
4
- <%= @_layout_content %>
5
- </body>
6
- </html>
@@ -1,11 +0,0 @@
1
- <ul>
2
- <% @comments.each do |c| %>
3
- <li><a onclick="new Ajax.Request('/posts/delete_comment/<%= c.id %>?post_id=<%= @post.id %>', {asynchronous:'true', evalScripts:'true'}); return false;" href="#">
4
- [X]
5
- </a>
6
- <%= c.name %><br />
7
- <%= c.body %>
8
- </li>
9
- <% end %>
10
- </ul>
11
-
@@ -1 +0,0 @@
1
- $('comments').update(<%=js partial(:comments) %>);
@@ -1,5 +0,0 @@
1
-
2
- <% @posts.each do |p| %>
3
- <h2><span><%= p.title %></span></h2>
4
- <div class="maintext"><%= p.body %></div>
5
- <% end %>
@@ -1,37 +0,0 @@
1
-
2
- <h2>Make a post doofus.</h2>
3
-
4
- <form action="/posts/create" method="post">
5
-
6
- <p>
7
- <label for="post_title">
8
-
9
- Title
10
-
11
- </label>
12
- <input type="text" size="30" name="title" id="post_title" />
13
- </p>
14
-
15
- <p>
16
- <label for="post_body">
17
-
18
- Body
19
-
20
- </label>
21
- <textarea cols="20" id="post_body" name="body" rows="20"></textarea>
22
- </p>
23
-
24
-
25
- <p>
26
- <input name="commit" type="submit" value="Submit" />
27
- </p>
28
- </form>
29
-
30
- <pre>
31
- <%= "session: #{session.to_yaml}" %>
32
- </pre>
33
-
34
-
35
- <% throw_content :sidebar do %>
36
- <h3>This is the sidebar thrown to the layout.</h3>
37
- <% end %>
@@ -1,37 +0,0 @@
1
-
2
- <h2><span><%= @post.title %></span></h2>
3
- <div class="maintext"><%= @post.body %></div>
4
- <br />
5
- <div id='comments'>
6
- <%= partial(:comments) %>
7
- </div>
8
-
9
- <form onsubmit="new Ajax.Request('/posts/add_comment?post_id=<%= @post.id %>',
10
- {asynchronous:'true',
11
- evalScripts:'true',
12
- parameters: Form.serialize(this)});
13
- return false;" method="post" action="/posts/add_comment">
14
-
15
- <p>
16
- <label for="comment_name">
17
-
18
- Name
19
-
20
- </label><br />
21
- <input type="text" size="20" name="comment_name" id="comment_name" />
22
- </p>
23
-
24
- <p>
25
- <label for="comment_body">
26
-
27
- Comment
28
-
29
- </label><br />
30
- <textarea cols="20" id="post_body" name="comment_body" rows="8"></textarea>
31
- </p>
32
-
33
-
34
- <p>
35
- <input name="commit" type="submit" value="Submit" />
36
- </p>
37
- </form>
@@ -1,3 +0,0 @@
1
- xml.foo {
2
- xml.bar "baz"
3
- }
@@ -1 +0,0 @@
1
- <h1>Nested Partial works!</h1>
@@ -1,2 +0,0 @@
1
-
2
- <%= @args.inspect %>
@@ -1,5 +0,0 @@
1
-
2
- <h1><%= params.inspect %></h1>
3
- <% 5.times do %>
4
- <h1>Hello, <%= @name %>!</h1>
5
- <% end %>
@@ -1 +0,0 @@
1
- <%= @post.attributes.inspect.to_json %>
@@ -1,11 +0,0 @@
1
- ---
2
- :host: 127.0.0.1
3
- :port: "4000"
4
- :allow_reloading: false
5
- #:sql_session: true
6
- #:basic_auth:
7
- # :username: ezra
8
- # :password: test
9
- # :domain: localhost
10
- #:daemonize: true
11
- #:cluster: 3
@@ -1,24 +0,0 @@
1
- puts "merb init called"
2
-
3
- # add your own ruby code here for app initialization and load path stuff
4
-
5
- require 'active_record'
6
-
7
-
8
- ActiveRecord::Base.logger = MERB_LOGGER
9
- ActiveRecord::Base.establish_connection(
10
- :adapter => 'mysql',
11
- :username => 'root',
12
- :password => 'reversal',
13
- :database => 'merb'
14
- )
15
- ActiveRecord::Base.verification_timeout = 14400
16
-
17
- Dir[DIST_ROOT+"/app/**/*.rb"].each { |m| require m }
18
- Dir[DIST_ROOT+"/plugins/*/init.rb"].each { |m| require m }
19
-
20
- module Merb
21
- class ViewContext
22
- include Merb::GlobalHelper
23
- end
24
- end
@@ -1,5 +0,0 @@
1
- # upload progress conf
2
- ---
3
- #:drb: true
4
- :path_info: /files/upload
5
- :frequency: 2
@@ -1,19 +0,0 @@
1
- # Merb::RouteMatcher is the request routing mapper for the merb framework.
2
- # You can define placeholder parts of the url with the :smbol notation.
3
- # so r.add '/foo/:bar/baz/:id', :class => 'Bar', :method => 'foo'
4
- # will match against a request to /foo/123/baz/456. It will then
5
- # use the class Bar as your merb controller and call the foo method on it.
6
- # the foo method will recieve a hash with {:bar => '123', :id => '456'}
7
- # as the content. So the :placeholders sections of your routes become
8
- # a hash of arguments to your controller methods.
9
- # The default route is installed
10
-
11
-
12
- puts "Compiling routes.."
13
- Merb::RouteMatcher.prepare do |r|
14
- r.add '/foo/:bar/baz/:id', :controller => 'Test', :action => 'foo'
15
- r.add '/bar/:bar_id/baz/:id', :controller => 'Test', :action => 'foo'
16
- r.add '/:controller/:action/:id'
17
- r.add '/bar/:*rest', :controller => 'Test', :action => 'glob'
18
- r.add '', :controller => 'posts', :action =>'list'
19
- end
@@ -1,975 +0,0 @@
1
- // Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2
- // Contributors:
3
- // Justin Palmer (http://encytemedia.com/)
4
- // Mark Pilgrim (http://diveintomark.org/)
5
- // Martin Bialasinki
6
- //
7
- // See scriptaculous.js for full license.
8
-
9
- // converts rgb() and #xxx to #xxxxxx format,
10
- // returns self (or first argument) if not convertable
11
- String.prototype.parseColor = function() {
12
- var color = '#';
13
- if(this.slice(0,4) == 'rgb(') {
14
- var cols = this.slice(4,this.length-1).split(',');
15
- var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
16
- } else {
17
- if(this.slice(0,1) == '#') {
18
- if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
19
- if(this.length==7) color = this.toLowerCase();
20
- }
21
- }
22
- return(color.length==7 ? color : (arguments[0] || this));
23
- }
24
-
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('');
32
- }
33
-
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('');
40
- }
41
-
42
- Element.setContentZoom = function(element, percent) {
43
- element = $(element);
44
- Element.setStyle(element, {fontSize: (percent/100) + 'em'});
45
- if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
46
- }
47
-
48
- Element.getOpacity = function(element){
49
- var opacity;
50
- if (opacity = Element.getStyle(element, 'opacity'))
51
- return parseFloat(opacity);
52
- if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/))
53
- if(opacity[1]) return parseFloat(opacity[1]) / 100;
54
- return 1.0;
55
- }
56
-
57
- Element.setOpacity = function(element, value){
58
- element= $(element);
59
- if (value == 1){
60
- Element.setStyle(element, { opacity:
61
- (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ?
62
- 0.999999 : 1.0 });
63
- if(/MSIE/.test(navigator.userAgent) && !window.opera)
64
- Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});
65
- } else {
66
- if(value < 0.00001) value = 0;
67
- Element.setStyle(element, {opacity: value});
68
- if(/MSIE/.test(navigator.userAgent) && !window.opera)
69
- Element.setStyle(element,
70
- { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
71
- 'alpha(opacity='+value*100+')' });
72
- }
73
- }
74
-
75
- Element.getInlineOpacity = function(element){
76
- return $(element).style.opacity || '';
77
- }
78
-
79
- Element.childrenWithClassName = function(element, className, findFirst) {
80
- var classNameRegExp = new RegExp("(^|\\s)" + className + "(\\s|$)");
81
- var results = $A($(element).getElementsByTagName('*'))[findFirst ? 'detect' : 'select']( function(c) {
82
- return (c.className && c.className.match(classNameRegExp));
83
- });
84
- if(!results) results = [];
85
- return results;
86
- }
87
-
88
- Element.forceRerendering = function(element) {
89
- try {
90
- element = $(element);
91
- var n = document.createTextNode(' ');
92
- element.appendChild(n);
93
- element.removeChild(n);
94
- } catch(e) { }
95
- };
96
-
97
- /*--------------------------------------------------------------------------*/
98
-
99
- Array.prototype.call = function() {
100
- var args = arguments;
101
- this.each(function(f){ f.apply(this, args) });
102
- }
103
-
104
- /*--------------------------------------------------------------------------*/
105
-
106
- var Effect = {
107
- _elementDoesNotExistError: {
108
- name: 'ElementDoesNotExistError',
109
- message: 'The specified DOM element does not exist, but is required for this effect to operate'
110
- },
111
- tagifyText: function(element) {
112
- if(typeof Builder == 'undefined')
113
- throw("Effect.tagifyText requires including script.aculo.us' builder.js library");
114
-
115
- var tagifyStyle = 'position:relative';
116
- if(/MSIE/.test(navigator.userAgent) && !window.opera) tagifyStyle += ';zoom:1';
117
- element = $(element);
118
- $A(element.childNodes).each( function(child) {
119
- if(child.nodeType==3) {
120
- child.nodeValue.toArray().each( function(character) {
121
- element.insertBefore(
122
- Builder.node('span',{style: tagifyStyle},
123
- character == ' ' ? String.fromCharCode(160) : character),
124
- child);
125
- });
126
- Element.remove(child);
127
- }
128
- });
129
- },
130
- multiple: function(element, effect) {
131
- var elements;
132
- if(((typeof element == 'object') ||
133
- (typeof element == 'function')) &&
134
- (element.length))
135
- elements = element;
136
- else
137
- elements = $(element).childNodes;
138
-
139
- var options = Object.extend({
140
- speed: 0.1,
141
- delay: 0.0
142
- }, arguments[2] || {});
143
- var masterDelay = options.delay;
144
-
145
- $A(elements).each( function(element, index) {
146
- new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
147
- });
148
- },
149
- PAIRS: {
150
- 'slide': ['SlideDown','SlideUp'],
151
- 'blind': ['BlindDown','BlindUp'],
152
- 'appear': ['Appear','Fade']
153
- },
154
- toggle: function(element, effect) {
155
- element = $(element);
156
- effect = (effect || 'appear').toLowerCase();
157
- var options = Object.extend({
158
- queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
159
- }, arguments[2] || {});
160
- Effect[element.visible() ?
161
- Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
162
- }
163
- };
164
-
165
- var Effect2 = Effect; // deprecated
166
-
167
- /* ------------- transitions ------------- */
168
-
169
- Effect.Transitions = {}
170
-
171
- Effect.Transitions.linear = Prototype.K;
172
-
173
- Effect.Transitions.sinoidal = function(pos) {
174
- return (-Math.cos(pos*Math.PI)/2) + 0.5;
175
- }
176
- Effect.Transitions.reverse = function(pos) {
177
- return 1-pos;
178
- }
179
- Effect.Transitions.flicker = function(pos) {
180
- return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
181
- }
182
- Effect.Transitions.wobble = function(pos) {
183
- return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
184
- }
185
- Effect.Transitions.pulse = function(pos) {
186
- return (Math.floor(pos*10) % 2 == 0 ?
187
- (pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10)));
188
- }
189
- Effect.Transitions.none = function(pos) {
190
- return 0;
191
- }
192
- Effect.Transitions.full = function(pos) {
193
- return 1;
194
- }
195
-
196
- /* ------------- core effects ------------- */
197
-
198
- Effect.ScopedQueue = Class.create();
199
- Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
200
- initialize: function() {
201
- this.effects = [];
202
- this.interval = null;
203
- },
204
- _each: function(iterator) {
205
- this.effects._each(iterator);
206
- },
207
- add: function(effect) {
208
- var timestamp = new Date().getTime();
209
-
210
- var position = (typeof effect.options.queue == 'string') ?
211
- effect.options.queue : effect.options.queue.position;
212
-
213
- switch(position) {
214
- case 'front':
215
- // move unstarted effects after this effect
216
- this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
217
- e.startOn += effect.finishOn;
218
- e.finishOn += effect.finishOn;
219
- });
220
- break;
221
- case 'end':
222
- // start effect after last queued effect has finished
223
- timestamp = this.effects.pluck('finishOn').max() || timestamp;
224
- break;
225
- }
226
-
227
- effect.startOn += timestamp;
228
- effect.finishOn += timestamp;
229
-
230
- if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
231
- this.effects.push(effect);
232
-
233
- if(!this.interval)
234
- this.interval = setInterval(this.loop.bind(this), 40);
235
- },
236
- remove: function(effect) {
237
- this.effects = this.effects.reject(function(e) { return e==effect });
238
- if(this.effects.length == 0) {
239
- clearInterval(this.interval);
240
- this.interval = null;
241
- }
242
- },
243
- loop: function() {
244
- var timePos = new Date().getTime();
245
- this.effects.invoke('loop', timePos);
246
- }
247
- });
248
-
249
- Effect.Queues = {
250
- instances: $H(),
251
- get: function(queueName) {
252
- if(typeof queueName != 'string') return queueName;
253
-
254
- if(!this.instances[queueName])
255
- this.instances[queueName] = new Effect.ScopedQueue();
256
-
257
- return this.instances[queueName];
258
- }
259
- }
260
- Effect.Queue = Effect.Queues.get('global');
261
-
262
- Effect.DefaultOptions = {
263
- transition: Effect.Transitions.sinoidal,
264
- duration: 1.0, // seconds
265
- fps: 25.0, // max. 25fps due to Effect.Queue implementation
266
- sync: false, // true for combining
267
- from: 0.0,
268
- to: 1.0,
269
- delay: 0.0,
270
- queue: 'parallel'
271
- }
272
-
273
- Effect.Base = function() {};
274
- Effect.Base.prototype = {
275
- position: null,
276
- start: function(options) {
277
- this.options = Object.extend(Object.extend({},Effect.DefaultOptions), options || {});
278
- this.currentFrame = 0;
279
- this.state = 'idle';
280
- this.startOn = this.options.delay*1000;
281
- this.finishOn = this.startOn + (this.options.duration*1000);
282
- this.event('beforeStart');
283
- if(!this.options.sync)
284
- Effect.Queues.get(typeof this.options.queue == 'string' ?
285
- 'global' : this.options.queue.scope).add(this);
286
- },
287
- loop: function(timePos) {
288
- if(timePos >= this.startOn) {
289
- if(timePos >= this.finishOn) {
290
- this.render(1.0);
291
- this.cancel();
292
- this.event('beforeFinish');
293
- if(this.finish) this.finish();
294
- this.event('afterFinish');
295
- return;
296
- }
297
- var pos = (timePos - this.startOn) / (this.finishOn - this.startOn);
298
- var frame = Math.round(pos * this.options.fps * this.options.duration);
299
- if(frame > this.currentFrame) {
300
- this.render(pos);
301
- this.currentFrame = frame;
302
- }
303
- }
304
- },
305
- render: function(pos) {
306
- if(this.state == 'idle') {
307
- this.state = 'running';
308
- this.event('beforeSetup');
309
- if(this.setup) this.setup();
310
- this.event('afterSetup');
311
- }
312
- if(this.state == 'running') {
313
- if(this.options.transition) pos = this.options.transition(pos);
314
- pos *= (this.options.to-this.options.from);
315
- pos += this.options.from;
316
- this.position = pos;
317
- this.event('beforeUpdate');
318
- if(this.update) this.update(pos);
319
- this.event('afterUpdate');
320
- }
321
- },
322
- cancel: function() {
323
- if(!this.options.sync)
324
- Effect.Queues.get(typeof this.options.queue == 'string' ?
325
- 'global' : this.options.queue.scope).remove(this);
326
- this.state = 'finished';
327
- },
328
- event: function(eventName) {
329
- if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
330
- if(this.options[eventName]) this.options[eventName](this);
331
- },
332
- inspect: function() {
333
- return '#<Effect:' + $H(this).inspect() + ',options:' + $H(this.options).inspect() + '>';
334
- }
335
- }
336
-
337
- Effect.Parallel = Class.create();
338
- Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
339
- initialize: function(effects) {
340
- this.effects = effects || [];
341
- this.start(arguments[1]);
342
- },
343
- update: function(position) {
344
- this.effects.invoke('render', position);
345
- },
346
- finish: function(position) {
347
- this.effects.each( function(effect) {
348
- effect.render(1.0);
349
- effect.cancel();
350
- effect.event('beforeFinish');
351
- if(effect.finish) effect.finish(position);
352
- effect.event('afterFinish');
353
- });
354
- }
355
- });
356
-
357
- Effect.Opacity = Class.create();
358
- Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
359
- initialize: function(element) {
360
- this.element = $(element);
361
- if(!this.element) throw(Effect._elementDoesNotExistError);
362
- // make this work on IE on elements without 'layout'
363
- if(/MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout))
364
- this.element.setStyle({zoom: 1});
365
- var options = Object.extend({
366
- from: this.element.getOpacity() || 0.0,
367
- to: 1.0
368
- }, arguments[1] || {});
369
- this.start(options);
370
- },
371
- update: function(position) {
372
- this.element.setOpacity(position);
373
- }
374
- });
375
-
376
- Effect.Move = Class.create();
377
- Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
378
- initialize: function(element) {
379
- this.element = $(element);
380
- if(!this.element) throw(Effect._elementDoesNotExistError);
381
- var options = Object.extend({
382
- x: 0,
383
- y: 0,
384
- mode: 'relative'
385
- }, arguments[1] || {});
386
- this.start(options);
387
- },
388
- setup: function() {
389
- // Bug in Opera: Opera returns the "real" position of a static element or
390
- // relative element that does not have top/left explicitly set.
391
- // ==> Always set top and left for position relative elements in your stylesheets
392
- // (to 0 if you do not need them)
393
- this.element.makePositioned();
394
- this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
395
- this.originalTop = parseFloat(this.element.getStyle('top') || '0');
396
- if(this.options.mode == 'absolute') {
397
- // absolute movement, so we need to calc deltaX and deltaY
398
- this.options.x = this.options.x - this.originalLeft;
399
- this.options.y = this.options.y - this.originalTop;
400
- }
401
- },
402
- update: function(position) {
403
- this.element.setStyle({
404
- left: Math.round(this.options.x * position + this.originalLeft) + 'px',
405
- top: Math.round(this.options.y * position + this.originalTop) + 'px'
406
- });
407
- }
408
- });
409
-
410
- // for backwards compatibility
411
- Effect.MoveBy = function(element, toTop, toLeft) {
412
- return new Effect.Move(element,
413
- Object.extend({ x: toLeft, y: toTop }, arguments[3] || {}));
414
- };
415
-
416
- Effect.Scale = Class.create();
417
- Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
418
- initialize: function(element, percent) {
419
- this.element = $(element);
420
- if(!this.element) throw(Effect._elementDoesNotExistError);
421
- var options = Object.extend({
422
- scaleX: true,
423
- scaleY: true,
424
- scaleContent: true,
425
- scaleFromCenter: false,
426
- scaleMode: 'box', // 'box' or 'contents' or {} with provided values
427
- scaleFrom: 100.0,
428
- scaleTo: percent
429
- }, arguments[2] || {});
430
- this.start(options);
431
- },
432
- setup: function() {
433
- this.restoreAfterFinish = this.options.restoreAfterFinish || false;
434
- this.elementPositioning = this.element.getStyle('position');
435
-
436
- this.originalStyle = {};
437
- ['top','left','width','height','fontSize'].each( function(k) {
438
- this.originalStyle[k] = this.element.style[k];
439
- }.bind(this));
440
-
441
- this.originalTop = this.element.offsetTop;
442
- this.originalLeft = this.element.offsetLeft;
443
-
444
- var fontSize = this.element.getStyle('font-size') || '100%';
445
- ['em','px','%','pt'].each( function(fontSizeType) {
446
- if(fontSize.indexOf(fontSizeType)>0) {
447
- this.fontSize = parseFloat(fontSize);
448
- this.fontSizeType = fontSizeType;
449
- }
450
- }.bind(this));
451
-
452
- this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
453
-
454
- this.dims = null;
455
- if(this.options.scaleMode=='box')
456
- this.dims = [this.element.offsetHeight, this.element.offsetWidth];
457
- if(/^content/.test(this.options.scaleMode))
458
- this.dims = [this.element.scrollHeight, this.element.scrollWidth];
459
- if(!this.dims)
460
- this.dims = [this.options.scaleMode.originalHeight,
461
- this.options.scaleMode.originalWidth];
462
- },
463
- update: function(position) {
464
- var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
465
- if(this.options.scaleContent && this.fontSize)
466
- this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
467
- this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
468
- },
469
- finish: function(position) {
470
- if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
471
- },
472
- setDimensions: function(height, width) {
473
- var d = {};
474
- if(this.options.scaleX) d.width = Math.round(width) + 'px';
475
- if(this.options.scaleY) d.height = Math.round(height) + 'px';
476
- if(this.options.scaleFromCenter) {
477
- var topd = (height - this.dims[0])/2;
478
- var leftd = (width - this.dims[1])/2;
479
- if(this.elementPositioning == 'absolute') {
480
- if(this.options.scaleY) d.top = this.originalTop-topd + 'px';
481
- if(this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
482
- } else {
483
- if(this.options.scaleY) d.top = -topd + 'px';
484
- if(this.options.scaleX) d.left = -leftd + 'px';
485
- }
486
- }
487
- this.element.setStyle(d);
488
- }
489
- });
490
-
491
- Effect.Highlight = Class.create();
492
- Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
493
- initialize: function(element) {
494
- this.element = $(element);
495
- if(!this.element) throw(Effect._elementDoesNotExistError);
496
- var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {});
497
- this.start(options);
498
- },
499
- setup: function() {
500
- // Prevent executing on elements not in the layout flow
501
- if(this.element.getStyle('display')=='none') { this.cancel(); return; }
502
- // Disable background image during the effect
503
- this.oldStyle = {
504
- backgroundImage: this.element.getStyle('background-image') };
505
- this.element.setStyle({backgroundImage: 'none'});
506
- if(!this.options.endcolor)
507
- this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
508
- if(!this.options.restorecolor)
509
- this.options.restorecolor = this.element.getStyle('background-color');
510
- // init color calculations
511
- this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
512
- 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));
513
- },
514
- update: function(position) {
515
- this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
516
- return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) });
517
- },
518
- finish: function() {
519
- this.element.setStyle(Object.extend(this.oldStyle, {
520
- backgroundColor: this.options.restorecolor
521
- }));
522
- }
523
- });
524
-
525
- Effect.ScrollTo = Class.create();
526
- Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
527
- initialize: function(element) {
528
- this.element = $(element);
529
- this.start(arguments[1] || {});
530
- },
531
- setup: function() {
532
- Position.prepare();
533
- var offsets = Position.cumulativeOffset(this.element);
534
- if(this.options.offset) offsets[1] += this.options.offset;
535
- var max = window.innerHeight ?
536
- window.height - window.innerHeight :
537
- document.body.scrollHeight -
538
- (document.documentElement.clientHeight ?
539
- document.documentElement.clientHeight : document.body.clientHeight);
540
- this.scrollStart = Position.deltaY;
541
- this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
542
- },
543
- update: function(position) {
544
- Position.prepare();
545
- window.scrollTo(Position.deltaX,
546
- this.scrollStart + (position*this.delta));
547
- }
548
- });
549
-
550
- /* ------------- combination effects ------------- */
551
-
552
- Effect.Fade = function(element) {
553
- element = $(element);
554
- var oldOpacity = element.getInlineOpacity();
555
- var options = Object.extend({
556
- from: element.getOpacity() || 1.0,
557
- to: 0.0,
558
- afterFinishInternal: function(effect) {
559
- if(effect.options.to!=0) return;
560
- effect.element.hide();
561
- effect.element.setStyle({opacity: oldOpacity});
562
- }}, arguments[1] || {});
563
- return new Effect.Opacity(element,options);
564
- }
565
-
566
- Effect.Appear = function(element) {
567
- element = $(element);
568
- var options = Object.extend({
569
- from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
570
- to: 1.0,
571
- // force Safari to render floated elements properly
572
- afterFinishInternal: function(effect) {
573
- effect.element.forceRerendering();
574
- },
575
- beforeSetup: function(effect) {
576
- effect.element.setOpacity(effect.options.from);
577
- effect.element.show();
578
- }}, arguments[1] || {});
579
- return new Effect.Opacity(element,options);
580
- }
581
-
582
- Effect.Puff = function(element) {
583
- element = $(element);
584
- var oldStyle = {
585
- opacity: element.getInlineOpacity(),
586
- position: element.getStyle('position'),
587
- top: element.style.top,
588
- left: element.style.left,
589
- width: element.style.width,
590
- height: element.style.height
591
- };
592
- return new Effect.Parallel(
593
- [ new Effect.Scale(element, 200,
594
- { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
595
- new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
596
- Object.extend({ duration: 1.0,
597
- beforeSetupInternal: function(effect) {
598
- Position.absolutize(effect.effects[0].element)
599
- },
600
- afterFinishInternal: function(effect) {
601
- effect.effects[0].element.hide();
602
- effect.effects[0].element.setStyle(oldStyle); }
603
- }, arguments[1] || {})
604
- );
605
- }
606
-
607
- Effect.BlindUp = function(element) {
608
- element = $(element);
609
- element.makeClipping();
610
- return new Effect.Scale(element, 0,
611
- Object.extend({ scaleContent: false,
612
- scaleX: false,
613
- restoreAfterFinish: true,
614
- afterFinishInternal: function(effect) {
615
- effect.element.hide();
616
- effect.element.undoClipping();
617
- }
618
- }, arguments[1] || {})
619
- );
620
- }
621
-
622
- Effect.BlindDown = function(element) {
623
- element = $(element);
624
- var elementDimensions = element.getDimensions();
625
- return new Effect.Scale(element, 100, Object.extend({
626
- scaleContent: false,
627
- scaleX: false,
628
- scaleFrom: 0,
629
- scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
630
- restoreAfterFinish: true,
631
- afterSetup: function(effect) {
632
- effect.element.makeClipping();
633
- effect.element.setStyle({height: '0px'});
634
- effect.element.show();
635
- },
636
- afterFinishInternal: function(effect) {
637
- effect.element.undoClipping();
638
- }
639
- }, arguments[1] || {}));
640
- }
641
-
642
- Effect.SwitchOff = function(element) {
643
- element = $(element);
644
- var oldOpacity = element.getInlineOpacity();
645
- return new Effect.Appear(element, Object.extend({
646
- duration: 0.4,
647
- from: 0,
648
- transition: Effect.Transitions.flicker,
649
- afterFinishInternal: function(effect) {
650
- new Effect.Scale(effect.element, 1, {
651
- duration: 0.3, scaleFromCenter: true,
652
- scaleX: false, scaleContent: false, restoreAfterFinish: true,
653
- beforeSetup: function(effect) {
654
- effect.element.makePositioned();
655
- effect.element.makeClipping();
656
- },
657
- afterFinishInternal: function(effect) {
658
- effect.element.hide();
659
- effect.element.undoClipping();
660
- effect.element.undoPositioned();
661
- effect.element.setStyle({opacity: oldOpacity});
662
- }
663
- })
664
- }
665
- }, arguments[1] || {}));
666
- }
667
-
668
- Effect.DropOut = function(element) {
669
- element = $(element);
670
- var oldStyle = {
671
- top: element.getStyle('top'),
672
- left: element.getStyle('left'),
673
- opacity: element.getInlineOpacity() };
674
- return new Effect.Parallel(
675
- [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
676
- new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
677
- Object.extend(
678
- { duration: 0.5,
679
- beforeSetup: function(effect) {
680
- effect.effects[0].element.makePositioned();
681
- },
682
- afterFinishInternal: function(effect) {
683
- effect.effects[0].element.hide();
684
- effect.effects[0].element.undoPositioned();
685
- effect.effects[0].element.setStyle(oldStyle);
686
- }
687
- }, arguments[1] || {}));
688
- }
689
-
690
- Effect.Shake = function(element) {
691
- element = $(element);
692
- var oldStyle = {
693
- top: element.getStyle('top'),
694
- left: element.getStyle('left') };
695
- return new Effect.Move(element,
696
- { x: 20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
697
- new Effect.Move(effect.element,
698
- { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
699
- new Effect.Move(effect.element,
700
- { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
701
- new Effect.Move(effect.element,
702
- { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
703
- new Effect.Move(effect.element,
704
- { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
705
- new Effect.Move(effect.element,
706
- { x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
707
- effect.element.undoPositioned();
708
- effect.element.setStyle(oldStyle);
709
- }}) }}) }}) }}) }}) }});
710
- }
711
-
712
- Effect.SlideDown = function(element) {
713
- element = $(element);
714
- element.cleanWhitespace();
715
- // SlideDown need to have the content of the element wrapped in a container element with fixed height!
716
- var oldInnerBottom = $(element.firstChild).getStyle('bottom');
717
- var elementDimensions = element.getDimensions();
718
- return new Effect.Scale(element, 100, Object.extend({
719
- scaleContent: false,
720
- scaleX: false,
721
- scaleFrom: window.opera ? 0 : 1,
722
- scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
723
- restoreAfterFinish: true,
724
- afterSetup: function(effect) {
725
- effect.element.makePositioned();
726
- effect.element.firstChild.makePositioned();
727
- if(window.opera) effect.element.setStyle({top: ''});
728
- effect.element.makeClipping();
729
- effect.element.setStyle({height: '0px'});
730
- effect.element.show(); },
731
- afterUpdateInternal: function(effect) {
732
- effect.element.firstChild.setStyle({bottom:
733
- (effect.dims[0] - effect.element.clientHeight) + 'px' });
734
- },
735
- afterFinishInternal: function(effect) {
736
- effect.element.undoClipping();
737
- // IE will crash if child is undoPositioned first
738
- if(/MSIE/.test(navigator.userAgent) && !window.opera){
739
- effect.element.undoPositioned();
740
- effect.element.firstChild.undoPositioned();
741
- }else{
742
- effect.element.firstChild.undoPositioned();
743
- effect.element.undoPositioned();
744
- }
745
- effect.element.firstChild.setStyle({bottom: oldInnerBottom}); }
746
- }, arguments[1] || {})
747
- );
748
- }
749
-
750
- Effect.SlideUp = function(element) {
751
- element = $(element);
752
- element.cleanWhitespace();
753
- var oldInnerBottom = $(element.firstChild).getStyle('bottom');
754
- return new Effect.Scale(element, window.opera ? 0 : 1,
755
- Object.extend({ scaleContent: false,
756
- scaleX: false,
757
- scaleMode: 'box',
758
- scaleFrom: 100,
759
- restoreAfterFinish: true,
760
- beforeStartInternal: function(effect) {
761
- effect.element.makePositioned();
762
- effect.element.firstChild.makePositioned();
763
- if(window.opera) effect.element.setStyle({top: ''});
764
- effect.element.makeClipping();
765
- effect.element.show(); },
766
- afterUpdateInternal: function(effect) {
767
- effect.element.firstChild.setStyle({bottom:
768
- (effect.dims[0] - effect.element.clientHeight) + 'px' }); },
769
- afterFinishInternal: function(effect) {
770
- effect.element.hide();
771
- effect.element.undoClipping();
772
- effect.element.firstChild.undoPositioned();
773
- effect.element.undoPositioned();
774
- effect.element.setStyle({bottom: oldInnerBottom}); }
775
- }, arguments[1] || {})
776
- );
777
- }
778
-
779
- // Bug in opera makes the TD containing this element expand for a instance after finish
780
- Effect.Squish = function(element) {
781
- return new Effect.Scale(element, window.opera ? 1 : 0,
782
- { restoreAfterFinish: true,
783
- beforeSetup: function(effect) {
784
- effect.element.makeClipping(effect.element); },
785
- afterFinishInternal: function(effect) {
786
- effect.element.hide(effect.element);
787
- effect.element.undoClipping(effect.element); }
788
- });
789
- }
790
-
791
- Effect.Grow = function(element) {
792
- element = $(element);
793
- var options = Object.extend({
794
- direction: 'center',
795
- moveTransition: Effect.Transitions.sinoidal,
796
- scaleTransition: Effect.Transitions.sinoidal,
797
- opacityTransition: Effect.Transitions.full
798
- }, arguments[1] || {});
799
- var oldStyle = {
800
- top: element.style.top,
801
- left: element.style.left,
802
- height: element.style.height,
803
- width: element.style.width,
804
- opacity: element.getInlineOpacity() };
805
-
806
- var dims = element.getDimensions();
807
- var initialMoveX, initialMoveY;
808
- var moveX, moveY;
809
-
810
- switch (options.direction) {
811
- case 'top-left':
812
- initialMoveX = initialMoveY = moveX = moveY = 0;
813
- break;
814
- case 'top-right':
815
- initialMoveX = dims.width;
816
- initialMoveY = moveY = 0;
817
- moveX = -dims.width;
818
- break;
819
- case 'bottom-left':
820
- initialMoveX = moveX = 0;
821
- initialMoveY = dims.height;
822
- moveY = -dims.height;
823
- break;
824
- case 'bottom-right':
825
- initialMoveX = dims.width;
826
- initialMoveY = dims.height;
827
- moveX = -dims.width;
828
- moveY = -dims.height;
829
- break;
830
- case 'center':
831
- initialMoveX = dims.width / 2;
832
- initialMoveY = dims.height / 2;
833
- moveX = -dims.width / 2;
834
- moveY = -dims.height / 2;
835
- break;
836
- }
837
-
838
- return new Effect.Move(element, {
839
- x: initialMoveX,
840
- y: initialMoveY,
841
- duration: 0.01,
842
- beforeSetup: function(effect) {
843
- effect.element.hide();
844
- effect.element.makeClipping();
845
- effect.element.makePositioned();
846
- },
847
- afterFinishInternal: function(effect) {
848
- new Effect.Parallel(
849
- [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
850
- new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
851
- new Effect.Scale(effect.element, 100, {
852
- scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
853
- sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
854
- ], Object.extend({
855
- beforeSetup: function(effect) {
856
- effect.effects[0].element.setStyle({height: '0px'});
857
- effect.effects[0].element.show();
858
- },
859
- afterFinishInternal: function(effect) {
860
- effect.effects[0].element.undoClipping();
861
- effect.effects[0].element.undoPositioned();
862
- effect.effects[0].element.setStyle(oldStyle);
863
- }
864
- }, options)
865
- )
866
- }
867
- });
868
- }
869
-
870
- Effect.Shrink = function(element) {
871
- element = $(element);
872
- var options = Object.extend({
873
- direction: 'center',
874
- moveTransition: Effect.Transitions.sinoidal,
875
- scaleTransition: Effect.Transitions.sinoidal,
876
- opacityTransition: Effect.Transitions.none
877
- }, arguments[1] || {});
878
- var oldStyle = {
879
- top: element.style.top,
880
- left: element.style.left,
881
- height: element.style.height,
882
- width: element.style.width,
883
- opacity: element.getInlineOpacity() };
884
-
885
- var dims = element.getDimensions();
886
- var moveX, moveY;
887
-
888
- switch (options.direction) {
889
- case 'top-left':
890
- moveX = moveY = 0;
891
- break;
892
- case 'top-right':
893
- moveX = dims.width;
894
- moveY = 0;
895
- break;
896
- case 'bottom-left':
897
- moveX = 0;
898
- moveY = dims.height;
899
- break;
900
- case 'bottom-right':
901
- moveX = dims.width;
902
- moveY = dims.height;
903
- break;
904
- case 'center':
905
- moveX = dims.width / 2;
906
- moveY = dims.height / 2;
907
- break;
908
- }
909
-
910
- return new Effect.Parallel(
911
- [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
912
- new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
913
- new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
914
- ], Object.extend({
915
- beforeStartInternal: function(effect) {
916
- effect.effects[0].element.makePositioned();
917
- effect.effects[0].element.makeClipping(); },
918
- afterFinishInternal: function(effect) {
919
- effect.effects[0].element.hide();
920
- effect.effects[0].element.undoClipping();
921
- effect.effects[0].element.undoPositioned();
922
- effect.effects[0].element.setStyle(oldStyle); }
923
- }, options)
924
- );
925
- }
926
-
927
- Effect.Pulsate = function(element) {
928
- element = $(element);
929
- var options = arguments[1] || {};
930
- var oldOpacity = element.getInlineOpacity();
931
- var transition = options.transition || Effect.Transitions.sinoidal;
932
- var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) };
933
- reverser.bind(transition);
934
- return new Effect.Opacity(element,
935
- Object.extend(Object.extend({ duration: 3.0, from: 0,
936
- afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
937
- }, options), {transition: reverser}));
938
- }
939
-
940
- Effect.Fold = function(element) {
941
- element = $(element);
942
- var oldStyle = {
943
- top: element.style.top,
944
- left: element.style.left,
945
- width: element.style.width,
946
- height: element.style.height };
947
- Element.makeClipping(element);
948
- return new Effect.Scale(element, 5, Object.extend({
949
- scaleContent: false,
950
- scaleX: false,
951
- afterFinishInternal: function(effect) {
952
- new Effect.Scale(element, 1, {
953
- scaleContent: false,
954
- scaleY: false,
955
- afterFinishInternal: function(effect) {
956
- effect.element.hide();
957
- effect.element.undoClipping();
958
- effect.element.setStyle(oldStyle);
959
- } });
960
- }}, arguments[1] || {}));
961
- };
962
-
963
- ['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom',
964
- 'collectTextNodes','collectTextNodesIgnoreClass','childrenWithClassName'].each(
965
- function(f) { Element.Methods[f] = Element[f]; }
966
- );
967
-
968
- Element.Methods.visualEffect = function(element, effect, options) {
969
- s = effect.gsub(/_/, '-').camelize();
970
- effect_class = s.charAt(0).toUpperCase() + s.substring(1);
971
- new Effect[effect_class](element, options);
972
- return $(element);
973
- };
974
-
975
- Element.addMethods();