parlement 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. data/CHANGES +709 -0
  2. data/COPYING +223 -0
  3. data/README +20 -0
  4. data/Rakefile +136 -0
  5. data/app/controllers/account_controller.rb +181 -0
  6. data/app/controllers/application.rb +30 -0
  7. data/app/controllers/elt_controller.rb +83 -0
  8. data/app/helpers/account_helper.rb +2 -0
  9. data/app/helpers/application_helper.rb +4 -0
  10. data/app/helpers/elt_helper.rb +37 -0
  11. data/app/helpers/live_tree.rb +238 -0
  12. data/app/helpers/mailman.rb +96 -0
  13. data/app/models/attachment.rb +4 -0
  14. data/app/models/elt.rb +17 -0
  15. data/app/models/mail.rb +4 -0
  16. data/app/models/notifier.rb +13 -0
  17. data/app/models/person.rb +9 -0
  18. data/app/models/user.rb +7 -0
  19. data/app/models/user_notify.rb +75 -0
  20. data/app/views/account/_help.rhtml +23 -0
  21. data/app/views/account/_login.rhtml +57 -0
  22. data/app/views/account/_show.rhtml +31 -0
  23. data/app/views/account/logout.rhtml +10 -0
  24. data/app/views/account/signup.rhtml +17 -0
  25. data/app/views/account/welcome.rhtml +13 -0
  26. data/app/views/elt/_elt.rhtml +105 -0
  27. data/app/views/elt/_form.rhtml +31 -0
  28. data/app/views/elt/_list.rhtml +28 -0
  29. data/app/views/elt/new.rhtml +102 -0
  30. data/app/views/elt/rss.rxml +31 -0
  31. data/app/views/elt/show.rhtml +46 -0
  32. data/app/views/elt/show_tree.rhtml +8 -0
  33. data/app/views/layouts/scaffold.rhtml +13 -0
  34. data/app/views/layouts/top.rhtml +45 -0
  35. data/app/views/notifier/changeEmail.rhtml +10 -0
  36. data/config/boot.rb +17 -0
  37. data/config/database.yml +82 -0
  38. data/config/environment.rb +92 -0
  39. data/config/environments/development.rb +17 -0
  40. data/config/environments/production.rb +17 -0
  41. data/config/environments/test.rb +17 -0
  42. data/config/environments/user_environment.rb +1 -0
  43. data/config/routes.rb +28 -0
  44. data/db/ROOT/CV.txt +166 -0
  45. data/db/ROOT/IP.txt +3 -0
  46. data/db/ROOT/parleR.txt +3 -0
  47. data/db/ROOT/parlement/security.txt +34 -0
  48. data/db/ROOT/parlement/test.txt +4 -0
  49. data/db/ROOT/parlement.txt +51 -0
  50. data/db/ROOT/perso.txt +215 -0
  51. data/db/schema.sql +127 -0
  52. data/lib/data_import.rb +54 -0
  53. data/lib/file_column.rb +263 -0
  54. data/lib/file_column_helper.rb +45 -0
  55. data/lib/localization.rb +88 -0
  56. data/lib/localizer.rb +88 -0
  57. data/lib/login_system.rb +87 -0
  58. data/lib/rails_file_column.rb +19 -0
  59. data/lib/user_system.rb +101 -0
  60. data/public/404.html +8 -0
  61. data/public/500.html +8 -0
  62. data/public/dispatch.cgi +10 -0
  63. data/public/dispatch.fcgi +24 -0
  64. data/public/dispatch.rb +10 -0
  65. data/public/engine_files/README +5 -0
  66. data/public/engine_files/login_engine/stylesheets/login_engine.css +81 -0
  67. data/public/favicon.ico +0 -0
  68. data/public/favicon.png +0 -0
  69. data/public/images/live_tree_branch_collapsed_icon.gif +0 -0
  70. data/public/images/live_tree_branch_expanded_icon.gif +0 -0
  71. data/public/images/live_tree_leaf_icon.gif +0 -0
  72. data/public/images/live_tree_loading_spinner.gif +0 -0
  73. data/public/images/webfeed.gif +0 -0
  74. data/public/javascripts/controls.js +721 -0
  75. data/public/javascripts/dragdrop.js +519 -0
  76. data/public/javascripts/effects.js +992 -0
  77. data/public/javascripts/live_tree.js +749 -0
  78. data/public/javascripts/prototype.js +1726 -0
  79. data/public/javascripts/scriptaculous.js +47 -0
  80. data/public/javascripts/slider.js +258 -0
  81. data/public/oldREADME +190 -0
  82. data/public/oldindex.html +78 -0
  83. data/public/robots.txt +1 -0
  84. data/public/stylesheets/default.css +238 -0
  85. data/public/stylesheets/live_tree.css +62 -0
  86. data/public/stylesheets/scaffold.css +74 -0
  87. data/script/about +3 -0
  88. data/script/benchmarker +19 -0
  89. data/script/breakpointer +3 -0
  90. data/script/console +3 -0
  91. data/script/create_db +7 -0
  92. data/script/destroy +3 -0
  93. data/script/generate +3 -0
  94. data/script/performance/benchmarker +3 -0
  95. data/script/performance/profiler +3 -0
  96. data/script/plugin +3 -0
  97. data/script/process/reaper +3 -0
  98. data/script/process/spawner +3 -0
  99. data/script/process/spinner +3 -0
  100. data/script/profiler +34 -0
  101. data/script/runner +3 -0
  102. data/script/server +3 -0
  103. data/test/fixtures/attachments.yml +10 -0
  104. data/test/fixtures/elts.yml +15 -0
  105. data/test/fixtures/mails.yml +7 -0
  106. data/test/fixtures/people.yml +49 -0
  107. data/test/fixtures/users.yml +41 -0
  108. data/test/functional/account_controller_test.rb +239 -0
  109. data/test/functional/elt_controller_test.rb +18 -0
  110. data/test/mocks/test/time.rb +17 -0
  111. data/test/mocks/test/user_notify.rb +16 -0
  112. data/test/test_helper.rb +28 -0
  113. data/test/unit/attachment_test.rb +14 -0
  114. data/test/unit/elt_test.rb +14 -0
  115. data/test/unit/mail_test.rb +14 -0
  116. data/test/unit/notifier_test.rb +31 -0
  117. data/test/unit/person_test.rb +24 -0
  118. data/test/unit/user_test.rb +94 -0
  119. data/vendor/plugins/engines/CHANGELOG +7 -0
  120. data/vendor/plugins/engines/README +128 -0
  121. data/vendor/plugins/engines/init.rb +33 -0
  122. data/vendor/plugins/engines/lib/action_mailer_extensions.rb +160 -0
  123. data/vendor/plugins/engines/lib/action_view_extensions.rb +130 -0
  124. data/vendor/plugins/engines/lib/dependencies_extensions.rb +56 -0
  125. data/vendor/plugins/engines/lib/engines.rb +292 -0
  126. data/vendor/plugins/engines/lib/ruby_extensions.rb +127 -0
  127. data/vendor/plugins/engines/lib/testing_extensions.rb +33 -0
  128. data/vendor/plugins/engines/test/ruby_extensions_test.rb +94 -0
  129. data/vendor/plugins/login_engine/README +258 -0
  130. data/vendor/plugins/login_engine/app/controllers/user_controller.rb +248 -0
  131. data/vendor/plugins/login_engine/app/helpers/user_helper.rb +88 -0
  132. data/vendor/plugins/login_engine/app/models/user.rb +7 -0
  133. data/vendor/plugins/login_engine/app/models/user_notify.rb +75 -0
  134. data/vendor/plugins/login_engine/app/views/user/_edit.rhtml +11 -0
  135. data/vendor/plugins/login_engine/app/views/user/_password.rhtml +9 -0
  136. data/vendor/plugins/login_engine/app/views/user/change_password.rhtml +17 -0
  137. data/vendor/plugins/login_engine/app/views/user/edit.rhtml +23 -0
  138. data/vendor/plugins/login_engine/app/views/user/forgot_password.rhtml +18 -0
  139. data/vendor/plugins/login_engine/app/views/user/home.rhtml +7 -0
  140. data/vendor/plugins/login_engine/app/views/user/login.rhtml +17 -0
  141. data/vendor/plugins/login_engine/app/views/user/logout.rhtml +8 -0
  142. data/vendor/plugins/login_engine/app/views/user/signup.rhtml +17 -0
  143. data/vendor/plugins/login_engine/app/views/user_notify/change_password.rhtml +10 -0
  144. data/vendor/plugins/login_engine/app/views/user_notify/delete.rhtml +5 -0
  145. data/vendor/plugins/login_engine/app/views/user_notify/forgot_password.rhtml +11 -0
  146. data/vendor/plugins/login_engine/app/views/user_notify/pending_delete.rhtml +9 -0
  147. data/vendor/plugins/login_engine/app/views/user_notify/signup.rhtml +12 -0
  148. data/vendor/plugins/login_engine/db/schema.rb +25 -0
  149. data/vendor/plugins/login_engine/init_engine.rb +10 -0
  150. data/vendor/plugins/login_engine/lib/login_engine/authenticated_system.rb +107 -0
  151. data/vendor/plugins/login_engine/lib/login_engine/authenticated_user.rb +149 -0
  152. data/vendor/plugins/login_engine/lib/login_engine.rb +58 -0
  153. data/vendor/plugins/login_engine/public/stylesheets/login_engine.css +81 -0
  154. data/vendor/plugins/login_engine/tasks/tasks.rake +4 -0
  155. data/vendor/plugins/login_engine/test/fixtures/templates/users.yml +41 -0
  156. data/vendor/plugins/login_engine/test/fixtures/users.yml +41 -0
  157. data/vendor/plugins/login_engine/test/functional/user_controller_test.rb +533 -0
  158. data/vendor/plugins/login_engine/test/mocks/mail.rb +14 -0
  159. data/vendor/plugins/login_engine/test/mocks/time.rb +19 -0
  160. data/vendor/plugins/login_engine/test/test_helper.rb +15 -0
  161. data/vendor/plugins/login_engine/test/unit/user_test.rb +94 -0
  162. metadata +276 -0
@@ -0,0 +1,519 @@
1
+ // Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2
+ //
3
+ // Element.Class part Copyright (c) 2005 by Rick Olson
4
+ //
5
+ // See scriptaculous.js for full license.
6
+
7
+ /*--------------------------------------------------------------------------*/
8
+
9
+ var Droppables = {
10
+ drops: [],
11
+
12
+ remove: function(element) {
13
+ this.drops = this.drops.reject(function(d) { return d.element==element });
14
+ },
15
+
16
+ add: function(element) {
17
+ element = $(element);
18
+ var options = Object.extend({
19
+ greedy: true,
20
+ hoverclass: null
21
+ }, arguments[1] || {});
22
+
23
+ // cache containers
24
+ if(options.containment) {
25
+ options._containers = [];
26
+ var containment = options.containment;
27
+ if((typeof containment == 'object') &&
28
+ (containment.constructor == Array)) {
29
+ containment.each( function(c) { options._containers.push($(c)) });
30
+ } else {
31
+ options._containers.push($(containment));
32
+ }
33
+ }
34
+
35
+ Element.makePositioned(element); // fix IE
36
+ options.element = element;
37
+
38
+ this.drops.push(options);
39
+ },
40
+
41
+ isContained: function(element, drop) {
42
+ var parentNode = element.parentNode;
43
+ return drop._containers.detect(function(c) { return parentNode == c });
44
+ },
45
+
46
+ isAffected: function(pX, pY, element, drop) {
47
+ return (
48
+ (drop.element!=element) &&
49
+ ((!drop._containers) ||
50
+ this.isContained(element, drop)) &&
51
+ ((!drop.accept) ||
52
+ (Element.Class.has_any(element, drop.accept))) &&
53
+ Position.within(drop.element, pX, pY) );
54
+ },
55
+
56
+ deactivate: function(drop) {
57
+ if(drop.hoverclass)
58
+ Element.Class.remove(drop.element, drop.hoverclass);
59
+ this.last_active = null;
60
+ },
61
+
62
+ activate: function(drop) {
63
+ if(this.last_active) this.deactivate(this.last_active);
64
+ if(drop.hoverclass)
65
+ Element.Class.add(drop.element, drop.hoverclass);
66
+ this.last_active = drop;
67
+ },
68
+
69
+ show: function(event, element) {
70
+ if(!this.drops.length) return;
71
+ var pX = Event.pointerX(event);
72
+ var pY = Event.pointerY(event);
73
+ Position.prepare();
74
+
75
+ var i = this.drops.length-1; do {
76
+ var drop = this.drops[i];
77
+ if(this.isAffected(pX, pY, element, drop)) {
78
+ if(drop.onHover)
79
+ drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
80
+ if(drop.greedy) {
81
+ this.activate(drop);
82
+ return;
83
+ }
84
+ }
85
+ } while (i--);
86
+
87
+ if(this.last_active) this.deactivate(this.last_active);
88
+ },
89
+
90
+ fire: function(event, element) {
91
+ if(!this.last_active) return;
92
+ Position.prepare();
93
+
94
+ if (this.isAffected(Event.pointerX(event), Event.pointerY(event), element, this.last_active))
95
+ if (this.last_active.onDrop)
96
+ this.last_active.onDrop(element, this.last_active.element, event);
97
+ },
98
+
99
+ reset: function() {
100
+ if(this.last_active)
101
+ this.deactivate(this.last_active);
102
+ }
103
+ }
104
+
105
+ var Draggables = {
106
+ observers: [],
107
+ addObserver: function(observer) {
108
+ this.observers.push(observer);
109
+ },
110
+ removeObserver: function(element) { // element instead of obsever fixes mem leaks
111
+ this.observers = this.observers.reject( function(o) { return o.element==element });
112
+ },
113
+ notify: function(eventName, draggable) { // 'onStart', 'onEnd'
114
+ this.observers.invoke(eventName, draggable);
115
+ }
116
+ }
117
+
118
+ /*--------------------------------------------------------------------------*/
119
+
120
+ var Draggable = Class.create();
121
+ Draggable.prototype = {
122
+ initialize: function(element) {
123
+ var options = Object.extend({
124
+ handle: false,
125
+ starteffect: function(element) {
126
+ new Effect.Opacity(element, {duration:0.2, from:1.0, to:0.7});
127
+ },
128
+ reverteffect: function(element, top_offset, left_offset) {
129
+ var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
130
+ new Effect.MoveBy(element, -top_offset, -left_offset, {duration:dur});
131
+ },
132
+ endeffect: function(element) {
133
+ new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0});
134
+ },
135
+ zindex: 1000,
136
+ revert: false
137
+ }, arguments[1] || {});
138
+
139
+ this.element = $(element);
140
+ if(options.handle && (typeof options.handle == 'string'))
141
+ this.handle = Element.Class.childrenWith(this.element, options.handle)[0];
142
+
143
+ if(!this.handle) this.handle = $(options.handle);
144
+ if(!this.handle) this.handle = this.element;
145
+
146
+ Element.makePositioned(this.element); // fix IE
147
+
148
+ this.offsetX = 0;
149
+ this.offsetY = 0;
150
+ this.originalLeft = this.currentLeft();
151
+ this.originalTop = this.currentTop();
152
+ this.originalX = this.element.offsetLeft;
153
+ this.originalY = this.element.offsetTop;
154
+
155
+ this.options = options;
156
+
157
+ this.active = false;
158
+ this.dragging = false;
159
+
160
+ this.eventMouseDown = this.startDrag.bindAsEventListener(this);
161
+ this.eventMouseUp = this.endDrag.bindAsEventListener(this);
162
+ this.eventMouseMove = this.update.bindAsEventListener(this);
163
+ this.eventKeypress = this.keyPress.bindAsEventListener(this);
164
+
165
+ this.registerEvents();
166
+ },
167
+ destroy: function() {
168
+ Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
169
+ this.unregisterEvents();
170
+ },
171
+ registerEvents: function() {
172
+ Event.observe(document, "mouseup", this.eventMouseUp);
173
+ Event.observe(document, "mousemove", this.eventMouseMove);
174
+ Event.observe(document, "keypress", this.eventKeypress);
175
+ Event.observe(this.handle, "mousedown", this.eventMouseDown);
176
+ },
177
+ unregisterEvents: function() {
178
+ //if(!this.active) return;
179
+ //Event.stopObserving(document, "mouseup", this.eventMouseUp);
180
+ //Event.stopObserving(document, "mousemove", this.eventMouseMove);
181
+ //Event.stopObserving(document, "keypress", this.eventKeypress);
182
+ },
183
+ currentLeft: function() {
184
+ return parseInt(this.element.style.left || '0');
185
+ },
186
+ currentTop: function() {
187
+ return parseInt(this.element.style.top || '0')
188
+ },
189
+ startDrag: function(event) {
190
+ if(Event.isLeftClick(event)) {
191
+
192
+ // abort on form elements, fixes a Firefox issue
193
+ var src = Event.element(event);
194
+ if(src.tagName && (
195
+ src.tagName=='INPUT' ||
196
+ src.tagName=='SELECT' ||
197
+ src.tagName=='BUTTON' ||
198
+ src.tagName=='TEXTAREA')) return;
199
+
200
+ // this.registerEvents();
201
+ this.active = true;
202
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
203
+ var offsets = Position.cumulativeOffset(this.element);
204
+ this.offsetX = (pointer[0] - offsets[0]);
205
+ this.offsetY = (pointer[1] - offsets[1]);
206
+ Event.stop(event);
207
+ }
208
+ },
209
+ finishDrag: function(event, success) {
210
+ // this.unregisterEvents();
211
+
212
+ this.active = false;
213
+ this.dragging = false;
214
+
215
+ if(this.options.ghosting) {
216
+ Position.relativize(this.element);
217
+ Element.remove(this._clone);
218
+ this._clone = null;
219
+ }
220
+
221
+ if(success) Droppables.fire(event, this.element);
222
+ Draggables.notify('onEnd', this);
223
+
224
+ var revert = this.options.revert;
225
+ if(revert && typeof revert == 'function') revert = revert(this.element);
226
+
227
+ if(revert && this.options.reverteffect) {
228
+ this.options.reverteffect(this.element,
229
+ this.currentTop()-this.originalTop,
230
+ this.currentLeft()-this.originalLeft);
231
+ } else {
232
+ this.originalLeft = this.currentLeft();
233
+ this.originalTop = this.currentTop();
234
+ }
235
+
236
+ if(this.options.zindex)
237
+ this.element.style.zIndex = this.originalZ;
238
+
239
+ if(this.options.endeffect)
240
+ this.options.endeffect(this.element);
241
+
242
+
243
+ Droppables.reset();
244
+ },
245
+ keyPress: function(event) {
246
+ if(this.active) {
247
+ if(event.keyCode==Event.KEY_ESC) {
248
+ this.finishDrag(event, false);
249
+ Event.stop(event);
250
+ }
251
+ }
252
+ },
253
+ endDrag: function(event) {
254
+ if(this.active && this.dragging) {
255
+ this.finishDrag(event, true);
256
+ Event.stop(event);
257
+ }
258
+ this.active = false;
259
+ this.dragging = false;
260
+ },
261
+ draw: function(event) {
262
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
263
+ var offsets = Position.cumulativeOffset(this.element);
264
+ offsets[0] -= this.currentLeft();
265
+ offsets[1] -= this.currentTop();
266
+ var style = this.element.style;
267
+ if((!this.options.constraint) || (this.options.constraint=='horizontal'))
268
+ style.left = (pointer[0] - offsets[0] - this.offsetX) + "px";
269
+ if((!this.options.constraint) || (this.options.constraint=='vertical'))
270
+ style.top = (pointer[1] - offsets[1] - this.offsetY) + "px";
271
+ if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
272
+ },
273
+ update: function(event) {
274
+ if(this.active) {
275
+ if(!this.dragging) {
276
+ var style = this.element.style;
277
+ this.dragging = true;
278
+
279
+ if(Element.getStyle(this.element,'position')=='')
280
+ style.position = "relative";
281
+
282
+ if(this.options.zindex) {
283
+ this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
284
+ style.zIndex = this.options.zindex;
285
+ }
286
+
287
+ if(this.options.ghosting) {
288
+ this._clone = this.element.cloneNode(true);
289
+ Position.absolutize(this.element);
290
+ this.element.parentNode.insertBefore(this._clone, this.element);
291
+ }
292
+
293
+ Draggables.notify('onStart', this);
294
+ if(this.options.starteffect) this.options.starteffect(this.element);
295
+ }
296
+
297
+ Droppables.show(event, this.element);
298
+ this.draw(event);
299
+ if(this.options.change) this.options.change(this);
300
+
301
+ // fix AppleWebKit rendering
302
+ if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
303
+
304
+ Event.stop(event);
305
+ }
306
+ }
307
+ }
308
+
309
+ /*--------------------------------------------------------------------------*/
310
+
311
+ var SortableObserver = Class.create();
312
+ SortableObserver.prototype = {
313
+ initialize: function(element, observer) {
314
+ this.element = $(element);
315
+ this.observer = observer;
316
+ this.lastValue = Sortable.serialize(this.element);
317
+ },
318
+ onStart: function() {
319
+ this.lastValue = Sortable.serialize(this.element);
320
+ },
321
+ onEnd: function() {
322
+ Sortable.unmark();
323
+ if(this.lastValue != Sortable.serialize(this.element))
324
+ this.observer(this.element)
325
+ }
326
+ }
327
+
328
+ var Sortable = {
329
+ sortables: new Array(),
330
+ options: function(element){
331
+ element = $(element);
332
+ return this.sortables.detect(function(s) { return s.element == element });
333
+ },
334
+ destroy: function(element){
335
+ element = $(element);
336
+ this.sortables.findAll(function(s) { return s.element == element }).each(function(s){
337
+ Draggables.removeObserver(s.element);
338
+ s.droppables.each(function(d){ Droppables.remove(d) });
339
+ s.draggables.invoke('destroy');
340
+ });
341
+ this.sortables = this.sortables.reject(function(s) { return s.element == element });
342
+ },
343
+ create: function(element) {
344
+ element = $(element);
345
+ var options = Object.extend({
346
+ element: element,
347
+ tag: 'li', // assumes li children, override with tag: 'tagname'
348
+ dropOnEmpty: false,
349
+ tree: false, // fixme: unimplemented
350
+ overlap: 'vertical', // one of 'vertical', 'horizontal'
351
+ constraint: 'vertical', // one of 'vertical', 'horizontal', false
352
+ containment: element, // also takes array of elements (or id's); or false
353
+ handle: false, // or a CSS class
354
+ only: false,
355
+ hoverclass: null,
356
+ ghosting: false,
357
+ format: null,
358
+ onChange: Prototype.emptyFunction,
359
+ onUpdate: Prototype.emptyFunction
360
+ }, arguments[1] || {});
361
+
362
+ // clear any old sortable with same element
363
+ this.destroy(element);
364
+
365
+ // build options for the draggables
366
+ var options_for_draggable = {
367
+ revert: true,
368
+ ghosting: options.ghosting,
369
+ constraint: options.constraint,
370
+ handle: options.handle };
371
+
372
+ if(options.starteffect)
373
+ options_for_draggable.starteffect = options.starteffect;
374
+
375
+ if(options.reverteffect)
376
+ options_for_draggable.reverteffect = options.reverteffect;
377
+ else
378
+ if(options.ghosting) options_for_draggable.reverteffect = function(element) {
379
+ element.style.top = 0;
380
+ element.style.left = 0;
381
+ };
382
+
383
+ if(options.endeffect)
384
+ options_for_draggable.endeffect = options.endeffect;
385
+
386
+ if(options.zindex)
387
+ options_for_draggable.zindex = options.zindex;
388
+
389
+ // build options for the droppables
390
+ var options_for_droppable = {
391
+ overlap: options.overlap,
392
+ containment: options.containment,
393
+ hoverclass: options.hoverclass,
394
+ onHover: Sortable.onHover,
395
+ greedy: !options.dropOnEmpty
396
+ }
397
+
398
+ // fix for gecko engine
399
+ Element.cleanWhitespace(element);
400
+
401
+ options.draggables = [];
402
+ options.droppables = [];
403
+
404
+ // make it so
405
+
406
+ // drop on empty handling
407
+ if(options.dropOnEmpty) {
408
+ Droppables.add(element,
409
+ {containment: options.containment, onHover: Sortable.onEmptyHover, greedy: false});
410
+ options.droppables.push(element);
411
+ }
412
+
413
+ (this.findElements(element, options) || []).each( function(e) {
414
+ // handles are per-draggable
415
+ var handle = options.handle ?
416
+ Element.Class.childrenWith(e, options.handle)[0] : e;
417
+ options.draggables.push(
418
+ new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
419
+ Droppables.add(e, options_for_droppable);
420
+ options.droppables.push(e);
421
+ });
422
+
423
+ // keep reference
424
+ this.sortables.push(options);
425
+
426
+ // for onupdate
427
+ Draggables.addObserver(new SortableObserver(element, options.onUpdate));
428
+
429
+ },
430
+
431
+ // return all suitable-for-sortable elements in a guaranteed order
432
+ findElements: function(element, options) {
433
+ if(!element.hasChildNodes()) return null;
434
+ var elements = [];
435
+ $A(element.childNodes).each( function(e) {
436
+ if(e.tagName && e.tagName==options.tag.toUpperCase() &&
437
+ (!options.only || (Element.Class.has(e, options.only))))
438
+ elements.push(e);
439
+ if(options.tree) {
440
+ var grandchildren = this.findElements(e, options);
441
+ if(grandchildren) elements.push(grandchildren);
442
+ }
443
+ });
444
+
445
+ return (elements.length>0 ? elements.flatten() : null);
446
+ },
447
+
448
+ onHover: function(element, dropon, overlap) {
449
+ if(overlap>0.5) {
450
+ Sortable.mark(dropon, 'before');
451
+ if(dropon.previousSibling != element) {
452
+ var oldParentNode = element.parentNode;
453
+ element.style.visibility = "hidden"; // fix gecko rendering
454
+ dropon.parentNode.insertBefore(element, dropon);
455
+ if(dropon.parentNode!=oldParentNode)
456
+ Sortable.options(oldParentNode).onChange(element);
457
+ Sortable.options(dropon.parentNode).onChange(element);
458
+ }
459
+ } else {
460
+ Sortable.mark(dropon, 'after');
461
+ var nextElement = dropon.nextSibling || null;
462
+ if(nextElement != element) {
463
+ var oldParentNode = element.parentNode;
464
+ element.style.visibility = "hidden"; // fix gecko rendering
465
+ dropon.parentNode.insertBefore(element, nextElement);
466
+ if(dropon.parentNode!=oldParentNode)
467
+ Sortable.options(oldParentNode).onChange(element);
468
+ Sortable.options(dropon.parentNode).onChange(element);
469
+ }
470
+ }
471
+ },
472
+
473
+ onEmptyHover: function(element, dropon) {
474
+ if(element.parentNode!=dropon) {
475
+ var oldParentNode = element.parentNode;
476
+ dropon.appendChild(element);
477
+ Sortable.options(oldParentNode).onChange(element);
478
+ Sortable.options(dropon).onChange(element);
479
+ }
480
+ },
481
+
482
+ unmark: function() {
483
+ if(Sortable._marker) Element.hide(Sortable._marker);
484
+ },
485
+
486
+ mark: function(dropon, position) {
487
+ // mark on ghosting only
488
+ var sortable = Sortable.options(dropon.parentNode);
489
+ if(sortable && !sortable.ghosting) return;
490
+
491
+ if(!Sortable._marker) {
492
+ Sortable._marker = $('dropmarker') || document.createElement('DIV');
493
+ Element.hide(Sortable._marker);
494
+ Element.Class.add(Sortable._marker, 'dropmarker');
495
+ Sortable._marker.style.position = 'absolute';
496
+ document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
497
+ }
498
+ var offsets = Position.cumulativeOffset(dropon);
499
+ Sortable._marker.style.top = offsets[1] + 'px';
500
+ if(position=='after') Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px';
501
+ Sortable._marker.style.left = offsets[0] + 'px';
502
+ Element.show(Sortable._marker);
503
+ },
504
+
505
+ serialize: function(element) {
506
+ element = $(element);
507
+ var sortableOptions = this.options(element);
508
+ var options = Object.extend({
509
+ tag: sortableOptions.tag,
510
+ only: sortableOptions.only,
511
+ name: element.id,
512
+ format: sortableOptions.format || /^[^_]*_(.*)$/
513
+ }, arguments[1] || {});
514
+ return $(this.findElements(element, options) || []).collect( function(item) {
515
+ return (encodeURIComponent(options.name) + "[]=" +
516
+ encodeURIComponent(item.id.match(options.format) ? item.id.match(options.format)[1] : ''));
517
+ }).join("&");
518
+ }
519
+ }