nitro 0.24.0 → 0.25.0

Sign up to get free protection for your applications and to get access to all the features.
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)