nitro 0.24.0 → 0.25.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 (67) hide show
  1. data/CHANGELOG +279 -0
  2. data/ProjectInfo +7 -7
  3. data/doc/AUTHORS +4 -2
  4. data/doc/RELEASES +96 -1
  5. data/lib/nitro.rb +5 -2
  6. data/lib/nitro/adapter/cgi.rb +1 -1
  7. data/lib/nitro/adapter/webrick.rb +7 -5
  8. data/lib/nitro/caching/output.rb +3 -2
  9. data/lib/nitro/cgi/utils.rb +8 -4
  10. data/lib/nitro/compiler.rb +9 -5
  11. data/lib/nitro/compiler/include.rb +42 -0
  12. data/lib/nitro/compiler/markup.rb +1 -1
  13. data/lib/nitro/compiler/morphing.rb +120 -50
  14. data/lib/nitro/compiler/squeeze.rb +2 -2
  15. data/lib/nitro/context.rb +9 -0
  16. data/lib/nitro/controller.rb +8 -4
  17. data/lib/nitro/dispatcher.rb +5 -5
  18. data/lib/nitro/dispatcher/nice.rb +16 -5
  19. data/lib/nitro/element.rb +30 -8
  20. data/lib/nitro/helper.rb +56 -0
  21. data/lib/nitro/{mixin → helper}/benchmark.rb +1 -1
  22. data/lib/nitro/{mixin → helper}/buffer.rb +1 -2
  23. data/lib/nitro/{mixin → helper}/debug.rb +1 -1
  24. data/lib/nitro/{mixin/helper.rb → helper/default.rb} +4 -4
  25. data/lib/nitro/{mixin → helper}/form.rb +3 -3
  26. data/lib/nitro/{mixin → helper}/javascript.rb +17 -1
  27. data/lib/nitro/{mixin → helper}/pager.rb +1 -1
  28. data/lib/nitro/{mixin → helper}/rss.rb +3 -3
  29. data/lib/nitro/{mixin → helper}/table.rb +1 -1
  30. data/lib/nitro/{mixin → helper}/xhtml.rb +2 -2
  31. data/lib/nitro/{mixin → helper}/xml.rb +1 -1
  32. data/lib/nitro/render.rb +16 -8
  33. data/lib/nitro/scaffold.rb +6 -6
  34. data/lib/nitro/server/runner.rb +12 -0
  35. data/lib/nitro/session/drbserver.rb +16 -1
  36. data/proto/public/js/builder.js +97 -0
  37. data/proto/public/js/controls.js +18 -5
  38. data/proto/public/js/dragdrop.js +8 -5
  39. data/proto/public/js/effects.js +185 -4
  40. data/proto/public/js/prototype.js +432 -178
  41. data/proto/public/js/scriptaculous.js +6 -2
  42. data/proto/public/js/slider.js +226 -0
  43. data/proto/public/js/unittest.js +363 -0
  44. data/proto/public/media/nitro.png +0 -0
  45. data/{script → proto/script}/scgi_ctl +0 -0
  46. data/{script → proto/script}/scgi_service +16 -8
  47. data/proto/src/skin.rb +24 -0
  48. data/{lib → src}/part/admin.rb +0 -0
  49. data/src/part/admin/controller.rb +47 -0
  50. data/{lib → src}/part/admin/skin.rb +0 -0
  51. data/src/part/admin/template/denied.xhtml +1 -0
  52. data/{lib → src}/part/admin/template/index.xhtml +0 -0
  53. data/test/nitro/{mixin → helper}/tc_pager.rb +2 -2
  54. data/test/nitro/{mixin → helper}/tc_rss.rb +3 -3
  55. data/test/nitro/{mixin → helper}/tc_table.rb +3 -3
  56. data/test/nitro/{mixin → helper}/tc_xhtml.rb +3 -3
  57. data/test/nitro/tc_caching.rb +4 -1
  58. data/test/nitro/tc_controller.rb +2 -2
  59. data/test/nitro/tc_element.rb +30 -0
  60. data/test/nitro/tc_helper.rb +36 -0
  61. data/test/nitro/tc_render.rb +1 -1
  62. metadata +70 -38
  63. data/lib/nitro/mixin/markup.rb +0 -122
  64. data/lib/part/admin/controller.rb +0 -28
  65. data/proto/README +0 -11
  66. data/proto/doc/README +0 -1
  67. data/proto/scgi.rb +0 -333
@@ -1,7 +1,7 @@
1
1
  require 'mega/orm_support'
2
2
 
3
3
  require 'nitro/compiler'
4
- require 'nitro/mixin/form'
4
+ require 'nitro/helper/form'
5
5
 
6
6
  module Nitro
7
7
 
@@ -15,8 +15,8 @@ module Scaffolding
15
15
 
16
16
  def self.append_features(base) # :nodoc:
17
17
  super
18
- base.send :include, FormMixin
19
- base.extend(ClassMethods)
18
+ base.helper :form
19
+ base.extend ClassMethods
20
20
  end
21
21
 
22
22
  def self.class_to_name(klass)
@@ -59,13 +59,13 @@ module Scaffolding
59
59
 
60
60
  # Add methods to the scaffolded class.
61
61
 
62
- unless klass.respond_to? :to_href
62
+ unless klass.instance_methods.include? 'to_href'
63
63
  klass.send(:define_method, :to_href) do
64
64
  "#{name}/#{@oid}"
65
65
  end
66
66
  end
67
67
 
68
- unless klass.respond_to? :to_edit_link
68
+ unless klass.instance_methods.include? 'to_edit_link'
69
69
  klass.send(:define_method, :to_edit_link) do |base|
70
70
  %{<a href="#{base}/#{name}/#{@oid}">#{self}</a>&nbsp;(<a href="#{base}/edit#{suffix}/#{@oid}">edit</a>, <a href="#{base}/delete#{suffix}/#{@oid}">del</a>)}
71
71
  end
@@ -137,7 +137,7 @@ module Scaffolding
137
137
  oid = oid.to_s # in case oid is a StringIO (multipart).
138
138
  obj = request.fill(#{klass}[oid], :assign_relations => true, :force_boolean => true)
139
139
  else
140
- obj = request.fill(#{klass}.new, :assign_relations => true)
140
+ obj = request.fill(#{klass}.create, :assign_relations => true)
141
141
  end
142
142
  unless obj.valid?
143
143
  session[:ERRORS] = obj.errors
@@ -17,6 +17,9 @@ module Nitro
17
17
  #
18
18
  # You can implement your own, custom version of the Runner
19
19
  # to run your custom web applications.
20
+ #--
21
+ # FIXME: Rename/Reimplement this class.
22
+ #++
20
23
 
21
24
  class Runner
22
25
 
@@ -194,6 +197,15 @@ class Runner
194
197
  when :live
195
198
  setup_live
196
199
  end
200
+
201
+ # Special setup for distributed sessions.
202
+ =begin
203
+ if defined?(Session) and defined?(DRbObject)
204
+ if Session.store.is_a?(DRbObject)
205
+ system('ruby ' + File.join(Nitro::LibPath, 'session', 'drbserver.rb') + ' --address #{Session.drb_address} --port #{Session.drb_port} --daemon')
206
+ end
207
+ end
208
+ =end
197
209
  end
198
210
 
199
211
  # Setup in debug mode.
@@ -8,10 +8,14 @@ require 'nitro/session'
8
8
 
9
9
  # A distributes session store implemented as
10
10
  # a simple DRb server.
11
+ #--
12
+ # TODO: add daemonize support.
13
+ #++
11
14
 
12
15
  address = '127.0.0.1'
13
16
  port = 9069
14
17
  debug = false
18
+ daemon = false
15
19
 
16
20
  parser = OptionParser.new do |opts|
17
21
 
@@ -30,7 +34,11 @@ parser = OptionParser.new do |opts|
30
34
  opts.on('-D', '--debug', 'Run in debug mode.') do |p|
31
35
  debug = true
32
36
  end
33
-
37
+
38
+ opts.on('-d', '--daemon', 'Run as daemon.') do |p|
39
+ daemon = true
40
+ end
41
+
34
42
  opts.on_tail('-h', '--help', 'Show this message.') do
35
43
  puts opts
36
44
  exit
@@ -63,6 +71,13 @@ if debug
63
71
 
64
72
  end
65
73
 
74
+ puts "Drb session server listening at druby://#{address}:#{port}."
75
+
76
+ if daemon
77
+ require 'daemons/daemonize'
78
+ Daemonize.daemonize()
79
+ end
80
+
66
81
  DRb.start_service("druby://#{address}:#{port}", sessions)
67
82
  DRb.thread.join
68
83
 
@@ -0,0 +1,97 @@
1
+ // Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2
+ //
3
+ // See scriptaculous.js for full license.
4
+
5
+ var Builder = {
6
+ NODEMAP: {
7
+ AREA: 'map',
8
+ CAPTION: 'table',
9
+ COL: 'table',
10
+ COLGROUP: 'table',
11
+ LEGEND: 'fieldset',
12
+ OPTGROUP: 'select',
13
+ OPTION: 'select',
14
+ PARAM: 'object',
15
+ TBODY: 'table',
16
+ TD: 'table',
17
+ TFOOT: 'table',
18
+ TH: 'table',
19
+ THEAD: 'table',
20
+ TR: 'table'
21
+ },
22
+ // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
23
+ // due to a Firefox bug
24
+ node: function(elementName) {
25
+ elementName = elementName.toUpperCase();
26
+
27
+ // try innerHTML approach
28
+ var parentTag = this.NODEMAP[elementName] || 'div';
29
+ var parentElement = document.createElement(parentTag);
30
+ parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
31
+ var element = parentElement.firstChild || null;
32
+
33
+ // see if browser added wrapping tags
34
+ if(element && (element.tagName != elementName))
35
+ element = element.getElementsByTagName(elementName)[0];
36
+
37
+ // fallback to createElement approach
38
+ if(!element) element = document.createElement(elementName);
39
+
40
+ // abort if nothing could be created
41
+ if(!element) return;
42
+
43
+ // attributes (or text)
44
+ if(arguments[1])
45
+ if(this._isStringOrNumber(arguments[1]) ||
46
+ (arguments[1] instanceof Array)) {
47
+ this._children(element, arguments[1]);
48
+ } else {
49
+ var attrs = this._attributes(arguments[1]);
50
+ if(attrs.length) {
51
+ parentElement.innerHTML = "<" +elementName + " " +
52
+ attrs + "></" + elementName + ">";
53
+ element = parentElement.firstChild || null;
54
+ // workaround firefox 1.0.X bug
55
+ if(!element) {
56
+ element = document.createElement(elementName);
57
+ for(attr in arguments[1])
58
+ element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
59
+ }
60
+ if(element.tagName != elementName)
61
+ element = parentElement.getElementsByTagName(elementName)[0];
62
+ }
63
+ }
64
+
65
+ // text, or array of children
66
+ if(arguments[2])
67
+ this._children(element, arguments[2]);
68
+
69
+ return element;
70
+ },
71
+ _text: function(text) {
72
+ return document.createTextNode(text);
73
+ },
74
+ _attributes: function(attributes) {
75
+ var attrs = [];
76
+ for(attribute in attributes)
77
+ attrs.push((attribute=='className' ? 'class' : attribute) +
78
+ '="' + attributes[attribute].toString().escapeHTML() + '"');
79
+ return attrs.join(" ");
80
+ },
81
+ _children: function(element, children) {
82
+ if(typeof children=='object') { // array can hold nodes and text
83
+ children.flatten().each( function(e) {
84
+ if(typeof e=='object')
85
+ element.appendChild(e)
86
+ else
87
+ if(Builder._isStringOrNumber(e))
88
+ element.appendChild(Builder._text(e));
89
+ });
90
+ } else
91
+ if(Builder._isStringOrNumber(children))
92
+ element.appendChild(Builder._text(children));
93
+ },
94
+ _isStringOrNumber: function(param) {
95
+ return(typeof param=='string' || typeof param=='number');
96
+ }
97
+ }
@@ -184,7 +184,10 @@ Autocompleter.Base.prototype = {
184
184
  this.show();
185
185
  this.active = true;
186
186
  }
187
- } else this.hide();
187
+ } else {
188
+ this.active = false;
189
+ this.hide();
190
+ }
188
191
  },
189
192
 
190
193
  markPrevious: function() {
@@ -425,6 +428,15 @@ Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), {
425
428
  //
426
429
  // see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor
427
430
 
431
+ // Use this if you notice weird scrolling problems on some browsers,
432
+ // the DOM might be a bit confused when this gets called so do this
433
+ // waits 1 ms (with setTimeout) until it does the activation
434
+ Field.scrollFreeActivate = function(field) {
435
+ setTimeout(function() {
436
+ Field.activate(field);
437
+ }, 1);
438
+ }
439
+
428
440
  Ajax.InPlaceEditor = Class.create();
429
441
  Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99";
430
442
  Ajax.InPlaceEditor.prototype = {
@@ -490,7 +502,7 @@ Ajax.InPlaceEditor.prototype = {
490
502
  Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener);
491
503
  }
492
504
  },
493
- enterEditMode: function() {
505
+ enterEditMode: function(evt) {
494
506
  if (this.saving) return;
495
507
  if (this.editing) return;
496
508
  this.editing = true;
@@ -501,11 +513,12 @@ Ajax.InPlaceEditor.prototype = {
501
513
  Element.hide(this.element);
502
514
  this.createForm();
503
515
  this.element.parentNode.insertBefore(this.form, this.element);
504
- Field.focus(this.editField);
516
+ Field.scrollFreeActivate(this.editField);
505
517
  // stop the event to avoid a page refresh in Safari
506
- if (arguments.length > 1) {
507
- Event.stop(arguments[0]);
518
+ if (evt) {
519
+ Event.stop(evt);
508
520
  }
521
+ return false;
509
522
  },
510
523
  createForm: function() {
511
524
  this.form = document.createElement("form");
@@ -233,8 +233,8 @@ Draggable.prototype = {
233
233
  this.originalTop = this.currentTop();
234
234
  }
235
235
 
236
- //if(this.options.zindex)
237
- //this.element.style.zIndex = this.originalZ;
236
+ if(this.options.zindex)
237
+ this.element.style.zIndex = this.originalZ;
238
238
 
239
239
  if(this.options.endeffect)
240
240
  this.options.endeffect(this.element);
@@ -280,7 +280,7 @@ Draggable.prototype = {
280
280
  style.position = "relative";
281
281
 
282
282
  if(this.options.zindex) {
283
- this.options.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
283
+ this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
284
284
  style.zIndex = this.options.zindex;
285
285
  }
286
286
 
@@ -355,8 +355,8 @@ var Sortable = {
355
355
  hoverclass: null,
356
356
  ghosting: false,
357
357
  format: null,
358
- onChange: function() {},
359
- onUpdate: function() {}
358
+ onChange: Prototype.emptyFunction,
359
+ onUpdate: Prototype.emptyFunction
360
360
  }, arguments[1] || {});
361
361
 
362
362
  // clear any old sortable with same element
@@ -472,7 +472,10 @@ var Sortable = {
472
472
 
473
473
  onEmptyHover: function(element, dropon) {
474
474
  if(element.parentNode!=dropon) {
475
+ var oldParentNode = element.parentNode;
475
476
  dropon.appendChild(element);
477
+ Sortable.options(oldParentNode).onChange(element);
478
+ Sortable.options(dropon).onChange(element);
476
479
  }
477
480
  },
478
481
 
@@ -4,7 +4,182 @@
4
4
  // Mark Pilgrim (http://diveintomark.org/)
5
5
  // Martin Bialasinki
6
6
  //
7
- // See scriptaculous.js for full license.
7
+ // See scriptaculous.js for full license.
8
+
9
+ /* ------------- element ext -------------- */
10
+
11
+ // converts rgb() and #xxx to #xxxxxx format,
12
+ // returns self (or first argument) if not convertable
13
+ String.prototype.parseColor = function() {
14
+ color = "#";
15
+ if(this.slice(0,4) == "rgb(") {
16
+ var cols = this.slice(4,this.length-1).split(',');
17
+ var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
18
+ } else {
19
+ if(this.slice(0,1) == '#') {
20
+ if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
21
+ if(this.length==7) color = this.toLowerCase();
22
+ }
23
+ }
24
+ return(color.length==7 ? color : (arguments[0] || this));
25
+ }
26
+
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;
42
+ }
43
+
44
+ Element.setContentZoom = function(element, percent) {
45
+ element = $(element);
46
+ element.style.fontSize = (percent/100) + "em";
47
+ if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
48
+ }
49
+
50
+ Element.getOpacity = function(element){
51
+ var opacity;
52
+ if (opacity = Element.getStyle(element, "opacity"))
53
+ return parseFloat(opacity);
54
+ if (opacity = (Element.getStyle(element, "filter") || '').match(/alpha\(opacity=(.*)\)/))
55
+ if(opacity[1]) return parseFloat(opacity[1]) / 100;
56
+ return 1.0;
57
+ }
58
+
59
+ Element.setOpacity = function(element, value){
60
+ element= $(element);
61
+ var els = element.style;
62
+ if (value == 1){
63
+ els.opacity = '0.999999';
64
+ if(/MSIE/.test(navigator.userAgent))
65
+ els.filter = Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'');
66
+ } else {
67
+ if(value < 0.00001) value = 0;
68
+ els.opacity = value;
69
+ if(/MSIE/.test(navigator.userAgent))
70
+ els.filter = Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
71
+ "alpha(opacity="+value*100+")";
72
+ }
73
+ }
74
+
75
+ Element.getInlineOpacity = function(element){
76
+ element= $(element);
77
+ var op;
78
+ op = element.style.opacity;
79
+ if (typeof op != "undefined" && op != "") return op;
80
+ return "";
81
+ }
82
+
83
+ Element.setInlineOpacity = function(element, value){
84
+ element= $(element);
85
+ var els = element.style;
86
+ els.opacity = value;
87
+ }
88
+
89
+ /*--------------------------------------------------------------------------*/
90
+
91
+ Element.Class = {
92
+ // Element.toggleClass(element, className) toggles the class being on/off
93
+ // Element.toggleClass(element, className1, className2) toggles between both classes,
94
+ // defaulting to className1 if neither exist
95
+ toggle: function(element, className) {
96
+ if(Element.Class.has(element, className)) {
97
+ Element.Class.remove(element, className);
98
+ if(arguments.length == 3) Element.Class.add(element, arguments[2]);
99
+ } else {
100
+ Element.Class.add(element, className);
101
+ if(arguments.length == 3) Element.Class.remove(element, arguments[2]);
102
+ }
103
+ },
104
+
105
+ // gets space-delimited classnames of an element as an array
106
+ get: function(element) {
107
+ return $(element).className.split(' ');
108
+ },
109
+
110
+ // functions adapted from original functions by Gavin Kistner
111
+ remove: function(element) {
112
+ element = $(element);
113
+ var removeClasses = arguments;
114
+ $R(1,arguments.length-1).each( function(index) {
115
+ element.className =
116
+ element.className.split(' ').reject(
117
+ function(klass) { return (klass == removeClasses[index]) } ).join(' ');
118
+ });
119
+ },
120
+
121
+ add: function(element) {
122
+ element = $(element);
123
+ for(var i = 1; i < arguments.length; i++) {
124
+ Element.Class.remove(element, arguments[i]);
125
+ element.className += (element.className.length > 0 ? ' ' : '') + arguments[i];
126
+ }
127
+ },
128
+
129
+ // returns true if all given classes exist in said element
130
+ has: function(element) {
131
+ element = $(element);
132
+ if(!element || !element.className) return false;
133
+ var regEx;
134
+ for(var i = 1; i < arguments.length; i++) {
135
+ if((typeof arguments[i] == 'object') &&
136
+ (arguments[i].constructor == Array)) {
137
+ for(var j = 0; j < arguments[i].length; j++) {
138
+ regEx = new RegExp("(^|\\s)" + arguments[i][j] + "(\\s|$)");
139
+ if(!regEx.test(element.className)) return false;
140
+ }
141
+ } else {
142
+ regEx = new RegExp("(^|\\s)" + arguments[i] + "(\\s|$)");
143
+ if(!regEx.test(element.className)) return false;
144
+ }
145
+ }
146
+ return true;
147
+ },
148
+
149
+ // expects arrays of strings and/or strings as optional paramters
150
+ // Element.Class.has_any(element, ['classA','classB','classC'], 'classD')
151
+ has_any: function(element) {
152
+ element = $(element);
153
+ if(!element || !element.className) return false;
154
+ var regEx;
155
+ for(var i = 1; i < arguments.length; i++) {
156
+ if((typeof arguments[i] == 'object') &&
157
+ (arguments[i].constructor == Array)) {
158
+ for(var j = 0; j < arguments[i].length; j++) {
159
+ regEx = new RegExp("(^|\\s)" + arguments[i][j] + "(\\s|$)");
160
+ if(regEx.test(element.className)) return true;
161
+ }
162
+ } else {
163
+ regEx = new RegExp("(^|\\s)" + arguments[i] + "(\\s|$)");
164
+ if(regEx.test(element.className)) return true;
165
+ }
166
+ }
167
+ return false;
168
+ },
169
+
170
+ childrenWith: function(element, className) {
171
+ var children = $(element).getElementsByTagName('*');
172
+ var elements = new Array();
173
+
174
+ for (var i = 0; i < children.length; i++)
175
+ if (Element.Class.has(children[i], className))
176
+ elements.push(children[i]);
177
+
178
+ return elements;
179
+ }
180
+ }
181
+
182
+ /*--------------------------------------------------------------------------*/
8
183
 
9
184
  var Effect = {
10
185
  tagifyText: function(element) {
@@ -81,6 +256,9 @@ Effect.Transitions.full = function(pos) {
81
256
 
82
257
  Effect.Queue = {
83
258
  effects: [],
259
+ _each: function(iterator) {
260
+ this.effects._each(iterator);
261
+ },
84
262
  interval: null,
85
263
  add: function(effect) {
86
264
  var timestamp = new Date().getTime();
@@ -117,6 +295,7 @@ Effect.Queue = {
117
295
  this.effects.invoke('loop', timePos);
118
296
  }
119
297
  }
298
+ Object.extend(Effect.Queue, Enumerable);
120
299
 
121
300
  Effect.Base = function() {};
122
301
  Effect.Base.prototype = {
@@ -342,6 +521,8 @@ Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype),
342
521
  this.start(options);
343
522
  },
344
523
  setup: function() {
524
+ // Prevent executing on elements not in the layout flow
525
+ if(this.element.style.display=='none') { this.cancel(); return; }
345
526
  // Disable background image during the effect
346
527
  this.oldBgImage = this.element.style.backgroundImage;
347
528
  this.element.style.backgroundImage = "none";
@@ -572,7 +753,7 @@ Effect.SlideDown = function(element) {
572
753
  },
573
754
  afterUpdateInternal: function(effect) {
574
755
  effect.element.firstChild.style.bottom =
575
- (effect.originalHeight - effect.element.clientHeight) + 'px'; },
756
+ (effect.dims[0] - effect.element.clientHeight) + 'px'; },
576
757
  afterFinishInternal: function(effect) {
577
758
  Element.undoClipping(effect.element);
578
759
  Element.undoPositioned(effect.element.firstChild);
@@ -599,7 +780,7 @@ Effect.SlideUp = function(element) {
599
780
  },
600
781
  afterUpdateInternal: function(effect) {
601
782
  effect.element.firstChild.style.bottom =
602
- (effect.originalHeight - effect.element.clientHeight) + 'px'; },
783
+ (effect.dims[0] - effect.element.clientHeight) + 'px'; },
603
784
  afterFinishInternal: function(effect) {
604
785
  Element.hide(effect.element);
605
786
  Element.undoClipping(effect.element);
@@ -697,7 +878,7 @@ Effect.Grow = function(element) {
697
878
  els.top = oldTop;
698
879
  els.left = oldLeft;
699
880
  els.height = oldHeight;
700
- els.width = originalWidth;
881
+ els.width = originalWidth + 'px';
701
882
  Element.setInlineOpacity(el, oldOpacity);
702
883
  }
703
884
  }, options)