rails 2.1.2 → 2.2.2

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

Potentially problematic release.


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

Files changed (221) hide show
  1. data/CHANGELOG +27 -3
  2. data/Rakefile +70 -10
  3. data/bin/about +0 -0
  4. data/bin/console +0 -0
  5. data/bin/destroy +0 -0
  6. data/bin/generate +0 -0
  7. data/bin/performance/benchmarker +0 -0
  8. data/bin/performance/profiler +0 -0
  9. data/bin/performance/request +0 -0
  10. data/bin/plugin +0 -0
  11. data/bin/process/inspector +0 -0
  12. data/bin/process/reaper +0 -0
  13. data/bin/process/spawner +0 -0
  14. data/bin/runner +0 -0
  15. data/bin/server +0 -0
  16. data/config.ru +17 -0
  17. data/configs/apache.conf +0 -0
  18. data/configs/databases/ibm_db.yml +62 -0
  19. data/configs/databases/mysql.yml +3 -0
  20. data/configs/databases/postgresql.yml +3 -0
  21. data/configs/databases/sqlite2.yml +3 -0
  22. data/configs/databases/sqlite3.yml +3 -0
  23. data/configs/locales/en.yml +5 -0
  24. data/dispatches/dispatch.fcgi +1 -1
  25. data/dispatches/dispatch.rb +2 -2
  26. data/dispatches/gateway.cgi +2 -2
  27. data/doc/README_FOR_APP +5 -2
  28. data/doc/guides/html/2_2_release_notes.html +1185 -0
  29. data/doc/guides/html/actioncontroller_basics.html +1270 -0
  30. data/doc/guides/html/activerecord_validations_callbacks.html +749 -0
  31. data/doc/guides/html/association_basics.html +2585 -0
  32. data/doc/guides/html/authors.html +240 -0
  33. data/doc/guides/html/benchmarking_and_profiling.html +1018 -0
  34. data/doc/guides/html/caching_with_rails.html +583 -0
  35. data/doc/guides/html/command_line.html +434 -0
  36. data/doc/guides/html/configuring.html +438 -0
  37. data/doc/guides/html/creating_plugins.html +1594 -0
  38. data/doc/guides/html/debugging_rails_applications.html +1175 -0
  39. data/doc/guides/html/finders.html +1090 -0
  40. data/doc/guides/html/form_helpers.html +638 -0
  41. data/doc/guides/html/getting_started_with_rails.html +2066 -0
  42. data/doc/guides/html/index.html +349 -0
  43. data/doc/guides/html/layouts_and_rendering.html +1406 -0
  44. data/doc/guides/html/migrations.html +921 -0
  45. data/doc/guides/html/routing_outside_in.html +2213 -0
  46. data/doc/guides/html/security.html +1346 -0
  47. data/doc/guides/html/testing_rails_applications.html +1859 -0
  48. data/doc/guides/source/2_2_release_notes.txt +435 -0
  49. data/doc/guides/source/actioncontroller_basics/changelog.txt +5 -0
  50. data/doc/guides/source/actioncontroller_basics/cookies.txt +34 -0
  51. data/doc/guides/source/actioncontroller_basics/csrf.txt +32 -0
  52. data/doc/guides/source/actioncontroller_basics/filters.txt +119 -0
  53. data/doc/guides/source/actioncontroller_basics/http_auth.txt +24 -0
  54. data/doc/guides/source/actioncontroller_basics/index.txt +40 -0
  55. data/doc/guides/source/actioncontroller_basics/introduction.txt +9 -0
  56. data/doc/guides/source/actioncontroller_basics/methods.txt +39 -0
  57. data/doc/guides/source/actioncontroller_basics/parameter_filtering.txt +14 -0
  58. data/doc/guides/source/actioncontroller_basics/params.txt +93 -0
  59. data/doc/guides/source/actioncontroller_basics/request_response_objects.txt +43 -0
  60. data/doc/guides/source/actioncontroller_basics/rescue.txt +67 -0
  61. data/doc/guides/source/actioncontroller_basics/session.txt +187 -0
  62. data/doc/guides/source/actioncontroller_basics/streaming.txt +91 -0
  63. data/doc/guides/source/actioncontroller_basics/verification.txt +40 -0
  64. data/doc/guides/source/active_record_basics.txt +181 -0
  65. data/doc/guides/source/activerecord_validations_callbacks.txt +404 -0
  66. data/doc/guides/source/association_basics.txt +1840 -0
  67. data/doc/guides/source/authors.txt +39 -0
  68. data/doc/guides/source/benchmarking_and_profiling/appendix.txt +95 -0
  69. data/doc/guides/source/benchmarking_and_profiling/digging_deeper.txt +105 -0
  70. data/doc/guides/source/benchmarking_and_profiling/edge_rails_features.txt +185 -0
  71. data/doc/guides/source/benchmarking_and_profiling/gameplan.txt +27 -0
  72. data/doc/guides/source/benchmarking_and_profiling/index.txt +242 -0
  73. data/doc/guides/source/benchmarking_and_profiling/rubyprof.txt +179 -0
  74. data/doc/guides/source/benchmarking_and_profiling/statistics.txt +57 -0
  75. data/doc/guides/source/caching_with_rails.txt +367 -0
  76. data/doc/guides/source/command_line.txt +147 -0
  77. data/doc/guides/source/configuring.txt +225 -0
  78. data/doc/guides/source/creating_plugins/acts_as_yaffle.txt +191 -0
  79. data/doc/guides/source/creating_plugins/appendix.txt +46 -0
  80. data/doc/guides/source/creating_plugins/controllers.txt +59 -0
  81. data/doc/guides/source/creating_plugins/core_ext.txt +123 -0
  82. data/doc/guides/source/creating_plugins/custom_route.txt +69 -0
  83. data/doc/guides/source/creating_plugins/gem.txt +1 -0
  84. data/doc/guides/source/creating_plugins/generator_method.txt +89 -0
  85. data/doc/guides/source/creating_plugins/helpers.txt +51 -0
  86. data/doc/guides/source/creating_plugins/index.txt +52 -0
  87. data/doc/guides/source/creating_plugins/migration_generator.txt +156 -0
  88. data/doc/guides/source/creating_plugins/models.txt +76 -0
  89. data/doc/guides/source/creating_plugins/odds_and_ends.txt +69 -0
  90. data/doc/guides/source/creating_plugins/test_setup.txt +230 -0
  91. data/doc/guides/source/debugging_rails_applications.txt +733 -0
  92. data/doc/guides/source/finders.txt +668 -0
  93. data/doc/guides/source/form_helpers.txt +345 -0
  94. data/doc/guides/source/getting_started_with_rails.txt +1256 -0
  95. data/doc/guides/source/images/belongs_to.png +0 -0
  96. data/doc/guides/source/images/bullet.gif +0 -0
  97. data/doc/guides/source/images/csrf.png +0 -0
  98. data/doc/guides/source/images/habtm.png +0 -0
  99. data/doc/guides/source/images/has_many.png +0 -0
  100. data/doc/guides/source/images/has_many_through.png +0 -0
  101. data/doc/guides/source/images/has_one.png +0 -0
  102. data/doc/guides/source/images/has_one_through.png +0 -0
  103. data/doc/guides/source/images/header_backdrop.png +0 -0
  104. data/doc/guides/source/images/icons/README +5 -0
  105. data/doc/guides/source/images/icons/callouts/1.png +0 -0
  106. data/doc/guides/source/images/icons/callouts/10.png +0 -0
  107. data/doc/guides/source/images/icons/callouts/11.png +0 -0
  108. data/doc/guides/source/images/icons/callouts/12.png +0 -0
  109. data/doc/guides/source/images/icons/callouts/13.png +0 -0
  110. data/doc/guides/source/images/icons/callouts/14.png +0 -0
  111. data/doc/guides/source/images/icons/callouts/15.png +0 -0
  112. data/doc/guides/source/images/icons/callouts/2.png +0 -0
  113. data/doc/guides/source/images/icons/callouts/3.png +0 -0
  114. data/doc/guides/source/images/icons/callouts/4.png +0 -0
  115. data/doc/guides/source/images/icons/callouts/5.png +0 -0
  116. data/doc/guides/source/images/icons/callouts/6.png +0 -0
  117. data/doc/guides/source/images/icons/callouts/7.png +0 -0
  118. data/doc/guides/source/images/icons/callouts/8.png +0 -0
  119. data/doc/guides/source/images/icons/callouts/9.png +0 -0
  120. data/doc/guides/source/images/icons/caution.png +0 -0
  121. data/doc/guides/source/images/icons/example.png +0 -0
  122. data/doc/guides/source/images/icons/home.png +0 -0
  123. data/doc/guides/source/images/icons/important.png +0 -0
  124. data/doc/guides/source/images/icons/next.png +0 -0
  125. data/doc/guides/source/images/icons/note.png +0 -0
  126. data/doc/guides/source/images/icons/prev.png +0 -0
  127. data/doc/guides/source/images/icons/tip.png +0 -0
  128. data/doc/guides/source/images/icons/up.png +0 -0
  129. data/doc/guides/source/images/icons/warning.png +0 -0
  130. data/doc/guides/source/images/polymorphic.png +0 -0
  131. data/doc/guides/source/images/rails_logo_remix.gif +0 -0
  132. data/doc/guides/source/images/ruby_on_rails_by_mike_rundle2.gif +0 -0
  133. data/doc/guides/source/images/session_fixation.png +0 -0
  134. data/doc/guides/source/index.txt +118 -0
  135. data/doc/guides/source/layouts_and_rendering.txt +982 -0
  136. data/doc/guides/source/migrations/anatomy_of_a_migration.txt +85 -0
  137. data/doc/guides/source/migrations/changelog.txt +5 -0
  138. data/doc/guides/source/migrations/creating_a_migration.txt +109 -0
  139. data/doc/guides/source/migrations/foreign_keys.txt +8 -0
  140. data/doc/guides/source/migrations/index.txt +22 -0
  141. data/doc/guides/source/migrations/rakeing_around.txt +111 -0
  142. data/doc/guides/source/migrations/scheming.txt +47 -0
  143. data/doc/guides/source/migrations/using_models_in_migrations.txt +46 -0
  144. data/doc/guides/source/migrations/writing_a_migration.txt +159 -0
  145. data/doc/guides/source/routing_outside_in.txt +986 -0
  146. data/doc/guides/source/security.txt +984 -0
  147. data/doc/guides/source/stylesheets/base.css +358 -0
  148. data/doc/guides/source/stylesheets/forms.css +35 -0
  149. data/doc/guides/source/stylesheets/more.css +82 -0
  150. data/doc/guides/source/templates/guides.html.erb +97 -0
  151. data/doc/guides/source/templates/inline.css +165 -0
  152. data/doc/guides/source/testing_rails_applications.txt +995 -0
  153. data/environments/boot.rb +2 -2
  154. data/environments/environment.rb +9 -1
  155. data/environments/production.rb +3 -1
  156. data/helpers/performance_test.rb +9 -0
  157. data/html/500.html +4 -1
  158. data/html/javascripts/controls.js +72 -72
  159. data/html/javascripts/dragdrop.js +165 -164
  160. data/html/javascripts/effects.js +173 -165
  161. data/html/javascripts/prototype.js +362 -267
  162. data/lib/commands/console.rb +13 -0
  163. data/lib/commands/dbconsole.rb +2 -2
  164. data/lib/commands/ncgi/listener +2 -2
  165. data/lib/commands/ncgi/tracker +2 -2
  166. data/lib/commands/plugin.rb +41 -24
  167. data/lib/commands/process/spawner.rb +4 -4
  168. data/lib/commands/runner.rb +1 -1
  169. data/lib/commands/server.rb +11 -1
  170. data/lib/commands/servers/thin.rb +25 -0
  171. data/lib/fcgi_handler.rb +1 -3
  172. data/lib/initializer.rb +162 -39
  173. data/lib/performance_test_help.rb +5 -0
  174. data/lib/rails/gem_builder.rb +3 -3
  175. data/lib/rails/gem_dependency.rb +155 -33
  176. data/lib/rails/mongrel_server/commands.rb +1 -1
  177. data/lib/rails/plugin.rb +10 -2
  178. data/lib/rails/rack.rb +6 -0
  179. data/lib/rails/rack/logger.rb +28 -0
  180. data/lib/rails/rack/static.rb +35 -0
  181. data/lib/rails/vendor_gem_source_index.rb +140 -0
  182. data/lib/rails/version.rb +1 -1
  183. data/lib/rails_generator/commands.rb +10 -16
  184. data/lib/rails_generator/generated_attribute.rb +4 -0
  185. data/lib/rails_generator/generators/applications/app/app_generator.rb +9 -3
  186. data/lib/rails_generator/generators/components/controller/controller_generator.rb +1 -1
  187. data/lib/rails_generator/generators/components/controller/templates/functional_test.rb +1 -1
  188. data/lib/rails_generator/generators/components/integration_test/integration_test_generator.rb +1 -1
  189. data/lib/rails_generator/generators/components/integration_test/templates/integration_test.rb +2 -2
  190. data/lib/rails_generator/generators/components/mailer/mailer_generator.rb +1 -1
  191. data/lib/rails_generator/generators/components/mailer/templates/unit_test.rb +2 -3
  192. data/lib/rails_generator/generators/components/model/model_generator.rb +1 -1
  193. data/lib/rails_generator/generators/components/model/templates/model.rb +3 -0
  194. data/lib/rails_generator/generators/components/model/templates/unit_test.rb +1 -1
  195. data/lib/rails_generator/generators/components/observer/observer_generator.rb +1 -1
  196. data/lib/rails_generator/generators/components/observer/templates/unit_test.rb +1 -1
  197. data/lib/rails_generator/generators/components/performance_test/USAGE +8 -0
  198. data/lib/rails_generator/generators/components/performance_test/performance_test_generator.rb +16 -0
  199. data/lib/rails_generator/generators/components/performance_test/templates/performance_test.rb +9 -0
  200. data/lib/rails_generator/generators/components/plugin/plugin_generator.rb +11 -11
  201. data/lib/rails_generator/generators/components/plugin/templates/Rakefile +1 -0
  202. data/lib/rails_generator/generators/components/plugin/templates/test_helper.rb +3 -0
  203. data/lib/rails_generator/generators/components/plugin/templates/unit_test.rb +4 -4
  204. data/lib/rails_generator/generators/components/resource/resource_generator.rb +2 -2
  205. data/lib/rails_generator/generators/components/resource/templates/functional_test.rb +1 -1
  206. data/lib/rails_generator/generators/components/scaffold/USAGE +9 -5
  207. data/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +10 -3
  208. data/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb +7 -7
  209. data/lib/rails_generator/scripts.rb +1 -1
  210. data/lib/rails_generator/scripts/destroy.rb +6 -7
  211. data/lib/rails_generator/secret_key_generator.rb +5 -147
  212. data/lib/tasks/annotations.rake +8 -11
  213. data/lib/tasks/databases.rake +42 -15
  214. data/lib/tasks/documentation.rake +15 -0
  215. data/lib/tasks/framework.rake +5 -1
  216. data/lib/tasks/gems.rake +24 -8
  217. data/lib/tasks/misc.rake +3 -4
  218. data/lib/tasks/testing.rake +25 -4
  219. data/lib/test_help.rb +1 -2
  220. data/lib/webrick_server.rb +2 -11
  221. metadata +165 -9
@@ -1,6 +1,6 @@
1
1
  // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2
- // (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
3
- //
2
+ // (c) 2005-2008 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
3
+ //
4
4
  // script.aculo.us is freely distributable under the terms of an MIT-style license.
5
5
  // For details, see the script.aculo.us web site: http://script.aculo.us/
6
6
 
@@ -32,7 +32,7 @@ var Droppables = {
32
32
  options._containers.push($(containment));
33
33
  }
34
34
  }
35
-
35
+
36
36
  if(options.accept) options.accept = [options.accept].flatten();
37
37
 
38
38
  Element.makePositioned(element); // fix IE
@@ -40,34 +40,34 @@ var Droppables = {
40
40
 
41
41
  this.drops.push(options);
42
42
  },
43
-
43
+
44
44
  findDeepestChild: function(drops) {
45
45
  deepest = drops[0];
46
-
46
+
47
47
  for (i = 1; i < drops.length; ++i)
48
48
  if (Element.isParent(drops[i].element, deepest.element))
49
49
  deepest = drops[i];
50
-
50
+
51
51
  return deepest;
52
52
  },
53
53
 
54
54
  isContained: function(element, drop) {
55
55
  var containmentNode;
56
56
  if(drop.tree) {
57
- containmentNode = element.treeNode;
57
+ containmentNode = element.treeNode;
58
58
  } else {
59
59
  containmentNode = element.parentNode;
60
60
  }
61
61
  return drop._containers.detect(function(c) { return containmentNode == c });
62
62
  },
63
-
63
+
64
64
  isAffected: function(point, element, drop) {
65
65
  return (
66
66
  (drop.element!=element) &&
67
67
  ((!drop._containers) ||
68
68
  this.isContained(element, drop)) &&
69
69
  ((!drop.accept) ||
70
- (Element.classNames(element).detect(
70
+ (Element.classNames(element).detect(
71
71
  function(v) { return drop.accept.include(v) } ) )) &&
72
72
  Position.within(drop.element, point[0], point[1]) );
73
73
  },
@@ -87,12 +87,12 @@ var Droppables = {
87
87
  show: function(point, element) {
88
88
  if(!this.drops.length) return;
89
89
  var drop, affected = [];
90
-
90
+
91
91
  this.drops.each( function(drop) {
92
92
  if(Droppables.isAffected(point, element, drop))
93
93
  affected.push(drop);
94
94
  });
95
-
95
+
96
96
  if(affected.length>0)
97
97
  drop = Droppables.findDeepestChild(affected);
98
98
 
@@ -101,7 +101,7 @@ var Droppables = {
101
101
  Position.within(drop.element, point[0], point[1]);
102
102
  if(drop.onHover)
103
103
  drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
104
-
104
+
105
105
  if (drop != this.last_active) Droppables.activate(drop);
106
106
  }
107
107
  },
@@ -112,8 +112,8 @@ var Droppables = {
112
112
 
113
113
  if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
114
114
  if (this.last_active.onDrop) {
115
- this.last_active.onDrop(element, this.last_active.element, event);
116
- return true;
115
+ this.last_active.onDrop(element, this.last_active.element, event);
116
+ return true;
117
117
  }
118
118
  },
119
119
 
@@ -121,25 +121,25 @@ var Droppables = {
121
121
  if(this.last_active)
122
122
  this.deactivate(this.last_active);
123
123
  }
124
- }
124
+ };
125
125
 
126
126
  var Draggables = {
127
127
  drags: [],
128
128
  observers: [],
129
-
129
+
130
130
  register: function(draggable) {
131
131
  if(this.drags.length == 0) {
132
132
  this.eventMouseUp = this.endDrag.bindAsEventListener(this);
133
133
  this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
134
134
  this.eventKeypress = this.keyPress.bindAsEventListener(this);
135
-
135
+
136
136
  Event.observe(document, "mouseup", this.eventMouseUp);
137
137
  Event.observe(document, "mousemove", this.eventMouseMove);
138
138
  Event.observe(document, "keypress", this.eventKeypress);
139
139
  }
140
140
  this.drags.push(draggable);
141
141
  },
142
-
142
+
143
143
  unregister: function(draggable) {
144
144
  this.drags = this.drags.reject(function(d) { return d==draggable });
145
145
  if(this.drags.length == 0) {
@@ -148,24 +148,24 @@ var Draggables = {
148
148
  Event.stopObserving(document, "keypress", this.eventKeypress);
149
149
  }
150
150
  },
151
-
151
+
152
152
  activate: function(draggable) {
153
- if(draggable.options.delay) {
154
- this._timeout = setTimeout(function() {
155
- Draggables._timeout = null;
156
- window.focus();
157
- Draggables.activeDraggable = draggable;
158
- }.bind(this), draggable.options.delay);
153
+ if(draggable.options.delay) {
154
+ this._timeout = setTimeout(function() {
155
+ Draggables._timeout = null;
156
+ window.focus();
157
+ Draggables.activeDraggable = draggable;
158
+ }.bind(this), draggable.options.delay);
159
159
  } else {
160
160
  window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
161
161
  this.activeDraggable = draggable;
162
162
  }
163
163
  },
164
-
164
+
165
165
  deactivate: function() {
166
166
  this.activeDraggable = null;
167
167
  },
168
-
168
+
169
169
  updateDrag: function(event) {
170
170
  if(!this.activeDraggable) return;
171
171
  var pointer = [Event.pointerX(event), Event.pointerY(event)];
@@ -173,36 +173,36 @@ var Draggables = {
173
173
  // the same coordinates, prevent needless redrawing (moz bug?)
174
174
  if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
175
175
  this._lastPointer = pointer;
176
-
176
+
177
177
  this.activeDraggable.updateDrag(event, pointer);
178
178
  },
179
-
179
+
180
180
  endDrag: function(event) {
181
- if(this._timeout) {
182
- clearTimeout(this._timeout);
183
- this._timeout = null;
181
+ if(this._timeout) {
182
+ clearTimeout(this._timeout);
183
+ this._timeout = null;
184
184
  }
185
185
  if(!this.activeDraggable) return;
186
186
  this._lastPointer = null;
187
187
  this.activeDraggable.endDrag(event);
188
188
  this.activeDraggable = null;
189
189
  },
190
-
190
+
191
191
  keyPress: function(event) {
192
192
  if(this.activeDraggable)
193
193
  this.activeDraggable.keyPress(event);
194
194
  },
195
-
195
+
196
196
  addObserver: function(observer) {
197
197
  this.observers.push(observer);
198
198
  this._cacheObserverCallbacks();
199
199
  },
200
-
200
+
201
201
  removeObserver: function(element) { // element instead of observer fixes mem leaks
202
202
  this.observers = this.observers.reject( function(o) { return o.element==element });
203
203
  this._cacheObserverCallbacks();
204
204
  },
205
-
205
+
206
206
  notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag'
207
207
  if(this[eventName+'Count'] > 0)
208
208
  this.observers.each( function(o) {
@@ -210,7 +210,7 @@ var Draggables = {
210
210
  });
211
211
  if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
212
212
  },
213
-
213
+
214
214
  _cacheObserverCallbacks: function() {
215
215
  ['onStart','onEnd','onDrag'].each( function(eventName) {
216
216
  Draggables[eventName+'Count'] = Draggables.observers.select(
@@ -218,7 +218,7 @@ var Draggables = {
218
218
  ).length;
219
219
  });
220
220
  }
221
- }
221
+ };
222
222
 
223
223
  /*--------------------------------------------------------------------------*/
224
224
 
@@ -234,12 +234,12 @@ var Draggable = Class.create({
234
234
  },
235
235
  endeffect: function(element) {
236
236
  var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0;
237
- new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
237
+ new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
238
238
  queue: {scope:'_draggable', position:'end'},
239
- afterFinish: function(){
240
- Draggable._dragging[element] = false
239
+ afterFinish: function(){
240
+ Draggable._dragging[element] = false
241
241
  }
242
- });
242
+ });
243
243
  },
244
244
  zindex: 1000,
245
245
  revert: false,
@@ -250,57 +250,57 @@ var Draggable = Class.create({
250
250
  snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] }
251
251
  delay: 0
252
252
  };
253
-
253
+
254
254
  if(!arguments[1] || Object.isUndefined(arguments[1].endeffect))
255
255
  Object.extend(defaults, {
256
256
  starteffect: function(element) {
257
257
  element._opacity = Element.getOpacity(element);
258
258
  Draggable._dragging[element] = true;
259
- new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
259
+ new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
260
260
  }
261
261
  });
262
-
262
+
263
263
  var options = Object.extend(defaults, arguments[1] || { });
264
264
 
265
265
  this.element = $(element);
266
-
266
+
267
267
  if(options.handle && Object.isString(options.handle))
268
268
  this.handle = this.element.down('.'+options.handle, 0);
269
-
269
+
270
270
  if(!this.handle) this.handle = $(options.handle);
271
271
  if(!this.handle) this.handle = this.element;
272
-
272
+
273
273
  if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
274
274
  options.scroll = $(options.scroll);
275
275
  this._isScrollChild = Element.childOf(this.element, options.scroll);
276
276
  }
277
277
 
278
- Element.makePositioned(this.element); // fix IE
278
+ Element.makePositioned(this.element); // fix IE
279
279
 
280
280
  this.options = options;
281
- this.dragging = false;
281
+ this.dragging = false;
282
282
 
283
283
  this.eventMouseDown = this.initDrag.bindAsEventListener(this);
284
284
  Event.observe(this.handle, "mousedown", this.eventMouseDown);
285
-
285
+
286
286
  Draggables.register(this);
287
287
  },
288
-
288
+
289
289
  destroy: function() {
290
290
  Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
291
291
  Draggables.unregister(this);
292
292
  },
293
-
293
+
294
294
  currentDelta: function() {
295
295
  return([
296
296
  parseInt(Element.getStyle(this.element,'left') || '0'),
297
297
  parseInt(Element.getStyle(this.element,'top') || '0')]);
298
298
  },
299
-
299
+
300
300
  initDrag: function(event) {
301
301
  if(!Object.isUndefined(Draggable._dragging[this.element]) &&
302
302
  Draggable._dragging[this.element]) return;
303
- if(Event.isLeftClick(event)) {
303
+ if(Event.isLeftClick(event)) {
304
304
  // abort on form elements, fixes a Firefox issue
305
305
  var src = Event.element(event);
306
306
  if((tag_name = src.tagName.toUpperCase()) && (
@@ -309,34 +309,34 @@ var Draggable = Class.create({
309
309
  tag_name=='OPTION' ||
310
310
  tag_name=='BUTTON' ||
311
311
  tag_name=='TEXTAREA')) return;
312
-
312
+
313
313
  var pointer = [Event.pointerX(event), Event.pointerY(event)];
314
314
  var pos = Position.cumulativeOffset(this.element);
315
315
  this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
316
-
316
+
317
317
  Draggables.activate(this);
318
318
  Event.stop(event);
319
319
  }
320
320
  },
321
-
321
+
322
322
  startDrag: function(event) {
323
323
  this.dragging = true;
324
324
  if(!this.delta)
325
325
  this.delta = this.currentDelta();
326
-
326
+
327
327
  if(this.options.zindex) {
328
328
  this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
329
329
  this.element.style.zIndex = this.options.zindex;
330
330
  }
331
-
331
+
332
332
  if(this.options.ghosting) {
333
333
  this._clone = this.element.cloneNode(true);
334
- this.element._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
335
- if (!this.element._originallyAbsolute)
334
+ this._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
335
+ if (!this._originallyAbsolute)
336
336
  Position.absolutize(this.element);
337
337
  this.element.parentNode.insertBefore(this._clone, this.element);
338
338
  }
339
-
339
+
340
340
  if(this.options.scroll) {
341
341
  if (this.options.scroll == window) {
342
342
  var where = this._getWindowScroll(this.options.scroll);
@@ -347,28 +347,28 @@ var Draggable = Class.create({
347
347
  this.originalScrollTop = this.options.scroll.scrollTop;
348
348
  }
349
349
  }
350
-
350
+
351
351
  Draggables.notify('onStart', this, event);
352
-
352
+
353
353
  if(this.options.starteffect) this.options.starteffect(this.element);
354
354
  },
355
-
355
+
356
356
  updateDrag: function(event, pointer) {
357
357
  if(!this.dragging) this.startDrag(event);
358
-
358
+
359
359
  if(!this.options.quiet){
360
360
  Position.prepare();
361
361
  Droppables.show(pointer, this.element);
362
362
  }
363
-
363
+
364
364
  Draggables.notify('onDrag', this, event);
365
-
365
+
366
366
  this.draw(pointer);
367
367
  if(this.options.change) this.options.change(this);
368
-
368
+
369
369
  if(this.options.scroll) {
370
370
  this.stopScrolling();
371
-
371
+
372
372
  var p;
373
373
  if (this.options.scroll == window) {
374
374
  with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
@@ -386,16 +386,16 @@ var Draggable = Class.create({
386
386
  if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
387
387
  this.startScrolling(speed);
388
388
  }
389
-
389
+
390
390
  // fix AppleWebKit rendering
391
391
  if(Prototype.Browser.WebKit) window.scrollBy(0,0);
392
-
392
+
393
393
  Event.stop(event);
394
394
  },
395
-
395
+
396
396
  finishDrag: function(event, success) {
397
397
  this.dragging = false;
398
-
398
+
399
399
  if(this.options.quiet){
400
400
  Position.prepare();
401
401
  var pointer = [Event.pointerX(event), Event.pointerY(event)];
@@ -403,24 +403,24 @@ var Draggable = Class.create({
403
403
  }
404
404
 
405
405
  if(this.options.ghosting) {
406
- if (!this.element._originallyAbsolute)
406
+ if (!this._originallyAbsolute)
407
407
  Position.relativize(this.element);
408
- delete this.element._originallyAbsolute;
408
+ delete this._originallyAbsolute;
409
409
  Element.remove(this._clone);
410
410
  this._clone = null;
411
411
  }
412
412
 
413
- var dropped = false;
414
- if(success) {
415
- dropped = Droppables.fire(event, this.element);
416
- if (!dropped) dropped = false;
413
+ var dropped = false;
414
+ if(success) {
415
+ dropped = Droppables.fire(event, this.element);
416
+ if (!dropped) dropped = false;
417
417
  }
418
418
  if(dropped && this.options.onDropped) this.options.onDropped(this.element);
419
419
  Draggables.notify('onEnd', this, event);
420
420
 
421
421
  var revert = this.options.revert;
422
422
  if(revert && Object.isFunction(revert)) revert = revert(this.element);
423
-
423
+
424
424
  var d = this.currentDelta();
425
425
  if(revert && this.options.reverteffect) {
426
426
  if (dropped == 0 || revert != 'failure')
@@ -433,67 +433,67 @@ var Draggable = Class.create({
433
433
  if(this.options.zindex)
434
434
  this.element.style.zIndex = this.originalZ;
435
435
 
436
- if(this.options.endeffect)
436
+ if(this.options.endeffect)
437
437
  this.options.endeffect(this.element);
438
-
438
+
439
439
  Draggables.deactivate(this);
440
440
  Droppables.reset();
441
441
  },
442
-
442
+
443
443
  keyPress: function(event) {
444
444
  if(event.keyCode!=Event.KEY_ESC) return;
445
445
  this.finishDrag(event, false);
446
446
  Event.stop(event);
447
447
  },
448
-
448
+
449
449
  endDrag: function(event) {
450
450
  if(!this.dragging) return;
451
451
  this.stopScrolling();
452
452
  this.finishDrag(event, true);
453
453
  Event.stop(event);
454
454
  },
455
-
455
+
456
456
  draw: function(point) {
457
457
  var pos = Position.cumulativeOffset(this.element);
458
458
  if(this.options.ghosting) {
459
459
  var r = Position.realOffset(this.element);
460
460
  pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
461
461
  }
462
-
462
+
463
463
  var d = this.currentDelta();
464
464
  pos[0] -= d[0]; pos[1] -= d[1];
465
-
465
+
466
466
  if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
467
467
  pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
468
468
  pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
469
469
  }
470
-
471
- var p = [0,1].map(function(i){
472
- return (point[i]-pos[i]-this.offset[i])
470
+
471
+ var p = [0,1].map(function(i){
472
+ return (point[i]-pos[i]-this.offset[i])
473
473
  }.bind(this));
474
-
474
+
475
475
  if(this.options.snap) {
476
476
  if(Object.isFunction(this.options.snap)) {
477
477
  p = this.options.snap(p[0],p[1],this);
478
478
  } else {
479
479
  if(Object.isArray(this.options.snap)) {
480
480
  p = p.map( function(v, i) {
481
- return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this))
481
+ return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this));
482
482
  } else {
483
483
  p = p.map( function(v) {
484
- return (v/this.options.snap).round()*this.options.snap }.bind(this))
484
+ return (v/this.options.snap).round()*this.options.snap }.bind(this));
485
485
  }
486
486
  }}
487
-
487
+
488
488
  var style = this.element.style;
489
489
  if((!this.options.constraint) || (this.options.constraint=='horizontal'))
490
490
  style.left = p[0] + "px";
491
491
  if((!this.options.constraint) || (this.options.constraint=='vertical'))
492
492
  style.top = p[1] + "px";
493
-
493
+
494
494
  if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
495
495
  },
496
-
496
+
497
497
  stopScrolling: function() {
498
498
  if(this.scrollInterval) {
499
499
  clearInterval(this.scrollInterval);
@@ -501,14 +501,14 @@ var Draggable = Class.create({
501
501
  Draggables._lastScrollPointer = null;
502
502
  }
503
503
  },
504
-
504
+
505
505
  startScrolling: function(speed) {
506
506
  if(!(speed[0] || speed[1])) return;
507
507
  this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
508
508
  this.lastScrolled = new Date();
509
509
  this.scrollInterval = setInterval(this.scroll.bind(this), 10);
510
510
  },
511
-
511
+
512
512
  scroll: function() {
513
513
  var current = new Date();
514
514
  var delta = current - this.lastScrolled;
@@ -524,7 +524,7 @@ var Draggable = Class.create({
524
524
  this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
525
525
  this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
526
526
  }
527
-
527
+
528
528
  Position.prepare();
529
529
  Droppables.show(Draggables._lastPointer, this.element);
530
530
  Draggables.notify('onDrag', this);
@@ -538,10 +538,10 @@ var Draggable = Class.create({
538
538
  Draggables._lastScrollPointer[1] = 0;
539
539
  this.draw(Draggables._lastScrollPointer);
540
540
  }
541
-
541
+
542
542
  if(this.options.change) this.options.change(this);
543
543
  },
544
-
544
+
545
545
  _getWindowScroll: function(w) {
546
546
  var T, L, W, H;
547
547
  with (w.document) {
@@ -560,7 +560,7 @@ var Draggable = Class.create({
560
560
  H = documentElement.clientHeight;
561
561
  } else {
562
562
  W = body.offsetWidth;
563
- H = body.offsetHeight
563
+ H = body.offsetHeight;
564
564
  }
565
565
  }
566
566
  return { top: T, left: L, width: W, height: H };
@@ -577,11 +577,11 @@ var SortableObserver = Class.create({
577
577
  this.observer = observer;
578
578
  this.lastValue = Sortable.serialize(this.element);
579
579
  },
580
-
580
+
581
581
  onStart: function() {
582
582
  this.lastValue = Sortable.serialize(this.element);
583
583
  },
584
-
584
+
585
585
  onEnd: function() {
586
586
  Sortable.unmark();
587
587
  if(this.lastValue != Sortable.serialize(this.element))
@@ -591,11 +591,11 @@ var SortableObserver = Class.create({
591
591
 
592
592
  var Sortable = {
593
593
  SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
594
-
594
+
595
595
  sortables: { },
596
-
596
+
597
597
  _findRootElement: function(element) {
598
- while (element.tagName.toUpperCase() != "BODY") {
598
+ while (element.tagName.toUpperCase() != "BODY") {
599
599
  if(element.id && Sortable.sortables[element.id]) return element;
600
600
  element = element.parentNode;
601
601
  }
@@ -606,22 +606,23 @@ var Sortable = {
606
606
  if(!element) return;
607
607
  return Sortable.sortables[element.id];
608
608
  },
609
-
609
+
610
610
  destroy: function(element){
611
- var s = Sortable.options(element);
612
-
611
+ element = $(element);
612
+ var s = Sortable.sortables[element.id];
613
+
613
614
  if(s) {
614
615
  Draggables.removeObserver(s.element);
615
616
  s.droppables.each(function(d){ Droppables.remove(d) });
616
617
  s.draggables.invoke('destroy');
617
-
618
+
618
619
  delete Sortable.sortables[s.element.id];
619
620
  }
620
621
  },
621
622
 
622
623
  create: function(element) {
623
624
  element = $(element);
624
- var options = Object.extend({
625
+ var options = Object.extend({
625
626
  element: element,
626
627
  tag: 'li', // assumes li children, override with tag: 'tagname'
627
628
  dropOnEmpty: false,
@@ -635,17 +636,17 @@ var Sortable = {
635
636
  delay: 0,
636
637
  hoverclass: null,
637
638
  ghosting: false,
638
- quiet: false,
639
+ quiet: false,
639
640
  scroll: false,
640
641
  scrollSensitivity: 20,
641
642
  scrollSpeed: 15,
642
643
  format: this.SERIALIZE_RULE,
643
-
644
- // these take arrays of elements or ids and can be
644
+
645
+ // these take arrays of elements or ids and can be
645
646
  // used for better initialization performance
646
647
  elements: false,
647
648
  handles: false,
648
-
649
+
649
650
  onChange: Prototype.emptyFunction,
650
651
  onUpdate: Prototype.emptyFunction
651
652
  }, arguments[1] || { });
@@ -682,24 +683,24 @@ var Sortable = {
682
683
  if(options.zindex)
683
684
  options_for_draggable.zindex = options.zindex;
684
685
 
685
- // build options for the droppables
686
+ // build options for the droppables
686
687
  var options_for_droppable = {
687
688
  overlap: options.overlap,
688
689
  containment: options.containment,
689
690
  tree: options.tree,
690
691
  hoverclass: options.hoverclass,
691
692
  onHover: Sortable.onHover
692
- }
693
-
693
+ };
694
+
694
695
  var options_for_tree = {
695
696
  onHover: Sortable.onEmptyHover,
696
697
  overlap: options.overlap,
697
698
  containment: options.containment,
698
699
  hoverclass: options.hoverclass
699
- }
700
+ };
700
701
 
701
702
  // fix for gecko engine
702
- Element.cleanWhitespace(element);
703
+ Element.cleanWhitespace(element);
703
704
 
704
705
  options.draggables = [];
705
706
  options.droppables = [];
@@ -712,14 +713,14 @@ var Sortable = {
712
713
 
713
714
  (options.elements || this.findElements(element, options) || []).each( function(e,i) {
714
715
  var handle = options.handles ? $(options.handles[i]) :
715
- (options.handle ? $(e).select('.' + options.handle)[0] : e);
716
+ (options.handle ? $(e).select('.' + options.handle)[0] : e);
716
717
  options.draggables.push(
717
718
  new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
718
719
  Droppables.add(e, options_for_droppable);
719
720
  if(options.tree) e.treeNode = element;
720
- options.droppables.push(e);
721
+ options.droppables.push(e);
721
722
  });
722
-
723
+
723
724
  if(options.tree) {
724
725
  (Sortable.findTreeElements(element, options) || []).each( function(e) {
725
726
  Droppables.add(e, options_for_tree);
@@ -741,7 +742,7 @@ var Sortable = {
741
742
  return Element.findChildren(
742
743
  element, options.only, options.tree ? true : false, options.tag);
743
744
  },
744
-
745
+
745
746
  findTreeElements: function(element, options) {
746
747
  return Element.findChildren(
747
748
  element, options.only, options.tree ? true : false, options.treeTag);
@@ -758,7 +759,7 @@ var Sortable = {
758
759
  var oldParentNode = element.parentNode;
759
760
  element.style.visibility = "hidden"; // fix gecko rendering
760
761
  dropon.parentNode.insertBefore(element, dropon);
761
- if(dropon.parentNode!=oldParentNode)
762
+ if(dropon.parentNode!=oldParentNode)
762
763
  Sortable.options(oldParentNode).onChange(element);
763
764
  Sortable.options(dropon.parentNode).onChange(element);
764
765
  }
@@ -769,26 +770,26 @@ var Sortable = {
769
770
  var oldParentNode = element.parentNode;
770
771
  element.style.visibility = "hidden"; // fix gecko rendering
771
772
  dropon.parentNode.insertBefore(element, nextElement);
772
- if(dropon.parentNode!=oldParentNode)
773
+ if(dropon.parentNode!=oldParentNode)
773
774
  Sortable.options(oldParentNode).onChange(element);
774
775
  Sortable.options(dropon.parentNode).onChange(element);
775
776
  }
776
777
  }
777
778
  },
778
-
779
+
779
780
  onEmptyHover: function(element, dropon, overlap) {
780
781
  var oldParentNode = element.parentNode;
781
782
  var droponOptions = Sortable.options(dropon);
782
-
783
+
783
784
  if(!Element.isParent(dropon, element)) {
784
785
  var index;
785
-
786
+
786
787
  var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
787
788
  var child = null;
788
-
789
+
789
790
  if(children) {
790
791
  var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
791
-
792
+
792
793
  for (index = 0; index < children.length; index += 1) {
793
794
  if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
794
795
  offset -= Element.offsetSize (children[index], droponOptions.overlap);
@@ -801,9 +802,9 @@ var Sortable = {
801
802
  }
802
803
  }
803
804
  }
804
-
805
+
805
806
  dropon.insertBefore(element, child);
806
-
807
+
807
808
  Sortable.options(oldParentNode).onChange(element);
808
809
  droponOptions.onChange(element);
809
810
  }
@@ -816,34 +817,34 @@ var Sortable = {
816
817
  mark: function(dropon, position) {
817
818
  // mark on ghosting only
818
819
  var sortable = Sortable.options(dropon.parentNode);
819
- if(sortable && !sortable.ghosting) return;
820
+ if(sortable && !sortable.ghosting) return;
820
821
 
821
822
  if(!Sortable._marker) {
822
- Sortable._marker =
823
+ Sortable._marker =
823
824
  ($('dropmarker') || Element.extend(document.createElement('DIV'))).
824
825
  hide().addClassName('dropmarker').setStyle({position:'absolute'});
825
826
  document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
826
- }
827
+ }
827
828
  var offsets = Position.cumulativeOffset(dropon);
828
829
  Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
829
-
830
+
830
831
  if(position=='after')
831
- if(sortable.overlap == 'horizontal')
832
+ if(sortable.overlap == 'horizontal')
832
833
  Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
833
834
  else
834
835
  Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
835
-
836
+
836
837
  Sortable._marker.show();
837
838
  },
838
-
839
+
839
840
  _tree: function(element, options, parent) {
840
841
  var children = Sortable.findElements(element, options) || [];
841
-
842
+
842
843
  for (var i = 0; i < children.length; ++i) {
843
844
  var match = children[i].id.match(options.format);
844
845
 
845
846
  if (!match) continue;
846
-
847
+
847
848
  var child = {
848
849
  id: encodeURIComponent(match ? match[1] : null),
849
850
  element: element,
@@ -851,16 +852,16 @@ var Sortable = {
851
852
  children: [],
852
853
  position: parent.children.length,
853
854
  container: $(children[i]).down(options.treeTag)
854
- }
855
-
855
+ };
856
+
856
857
  /* Get the element containing the children and recurse over it */
857
858
  if (child.container)
858
- this._tree(child.container, options, child)
859
-
859
+ this._tree(child.container, options, child);
860
+
860
861
  parent.children.push (child);
861
862
  }
862
863
 
863
- return parent;
864
+ return parent;
864
865
  },
865
866
 
866
867
  tree: function(element) {
@@ -873,15 +874,15 @@ var Sortable = {
873
874
  name: element.id,
874
875
  format: sortableOptions.format
875
876
  }, arguments[1] || { });
876
-
877
+
877
878
  var root = {
878
879
  id: null,
879
880
  parent: null,
880
881
  children: [],
881
882
  container: element,
882
883
  position: 0
883
- }
884
-
884
+ };
885
+
885
886
  return Sortable._tree(element, options, root);
886
887
  },
887
888
 
@@ -897,7 +898,7 @@ var Sortable = {
897
898
  sequence: function(element) {
898
899
  element = $(element);
899
900
  var options = Object.extend(this.options(element), arguments[1] || { });
900
-
901
+
901
902
  return $(this.findElements(element, options) || []).map( function(item) {
902
903
  return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
903
904
  });
@@ -906,14 +907,14 @@ var Sortable = {
906
907
  setSequence: function(element, new_sequence) {
907
908
  element = $(element);
908
909
  var options = Object.extend(this.options(element), arguments[2] || { });
909
-
910
+
910
911
  var nodeMap = { };
911
912
  this.findElements(element, options).each( function(n) {
912
913
  if (n.id.match(options.format))
913
914
  nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
914
915
  n.parentNode.removeChild(n);
915
916
  });
916
-
917
+
917
918
  new_sequence.each(function(ident) {
918
919
  var n = nodeMap[ident];
919
920
  if (n) {
@@ -922,16 +923,16 @@ var Sortable = {
922
923
  }
923
924
  });
924
925
  },
925
-
926
+
926
927
  serialize: function(element) {
927
928
  element = $(element);
928
929
  var options = Object.extend(Sortable.options(element), arguments[1] || { });
929
930
  var name = encodeURIComponent(
930
931
  (arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
931
-
932
+
932
933
  if (options.tree) {
933
934
  return Sortable.tree(element, arguments[1]).children.map( function (item) {
934
- return [name + Sortable._constructIndex(item) + "[id]=" +
935
+ return [name + Sortable._constructIndex(item) + "[id]=" +
935
936
  encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
936
937
  }).flatten().join('&');
937
938
  } else {
@@ -940,16 +941,16 @@ var Sortable = {
940
941
  }).join('&');
941
942
  }
942
943
  }
943
- }
944
+ };
944
945
 
945
946
  // Returns true if child is contained within element
946
947
  Element.isParent = function(child, element) {
947
948
  if (!child.parentNode || child == element) return false;
948
949
  if (child.parentNode == element) return true;
949
950
  return Element.isParent(child.parentNode, element);
950
- }
951
+ };
951
952
 
952
- Element.findChildren = function(element, only, recursive, tagName) {
953
+ Element.findChildren = function(element, only, recursive, tagName) {
953
954
  if(!element.hasChildNodes()) return null;
954
955
  tagName = tagName.toUpperCase();
955
956
  if(only) only = [only].flatten();
@@ -965,8 +966,8 @@ Element.findChildren = function(element, only, recursive, tagName) {
965
966
  });
966
967
 
967
968
  return (elements.length>0 ? elements.flatten() : []);
968
- }
969
+ };
969
970
 
970
971
  Element.offsetSize = function (element, type) {
971
972
  return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
972
- }
973
+ };