backlog 0.35.5 → 0.36.2

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 (150) hide show
  1. data/Gemfile +19 -0
  2. data/Gemfile~ +4 -0
  3. data/History.txt +25 -0
  4. data/Rakefile +3 -3
  5. data/app/controllers/{application.rb → application_controller.rb} +1 -2
  6. data/app/controllers/backlogs_controller.rb +0 -16
  7. data/app/controllers/search_controller.rb +0 -2
  8. data/app/controllers/user_controller.rb +7 -7
  9. data/app/controllers/work_locks_controller.rb +2 -2
  10. data/app/controllers/works_controller.rb +23 -23
  11. data/app/helpers/application_helper.rb +9 -6
  12. data/app/helpers/backlogs_helper.rb +1 -1
  13. data/app/helpers/periods_helper.rb +1 -1
  14. data/app/models/backlog.rb +13 -10
  15. data/app/models/period.rb +0 -5
  16. data/app/models/sidebar.rb +1 -0
  17. data/app/models/task.rb +4 -10
  18. data/app/models/user.rb +5 -6
  19. data/app/models/user_notify.rb +0 -1
  20. data/app/models/work.rb +20 -25
  21. data/app/models/works_report_filter.rb +4 -4
  22. data/app/views/backlogs/_buttons.rhtml +1 -1
  23. data/app/views/backlogs/_form.rhtml +5 -9
  24. data/app/views/layouts/_left_top.rhtml +0 -1
  25. data/app/views/periods/_form.rhtml +1 -1
  26. data/app/views/search/results.rhtml +1 -12
  27. data/app/views/task_notify/{invite_en.rhtml → invite.en.html.erb} +0 -0
  28. data/app/views/task_notify/{invite_no.rhtml → invite.no.html.erb} +0 -0
  29. data/app/views/tasks/_task.rhtml +49 -50
  30. data/app/views/tasks/edit.rhtml +4 -4
  31. data/app/views/tasks/start_work.rjs +1 -1
  32. data/app/views/user/_edit.rhtml +1 -1
  33. data/app/views/user/change_password.rhtml +1 -1
  34. data/app/views/user/edit.rhtml +4 -4
  35. data/app/views/user/signup.rhtml +2 -2
  36. data/app/views/user_notify/{change_password_en.rhtml → change_password.en.html.erb} +0 -0
  37. data/app/views/user_notify/{change_password_no.rhtml → change_password.no.html.erb} +0 -0
  38. data/app/views/user_notify/{forgot_password_en.rhtml → forgot_password.en.html.erb} +0 -0
  39. data/app/views/user_notify/{forgot_password_no.rhtml → forgot_password.no.html.erb} +0 -0
  40. data/app/views/user_notify/{monitoring_en.rhtml → monitoring.en.html.erb} +0 -0
  41. data/app/views/user_notify/{monitoring_no.rhtml → monitoring.no.html.erb} +0 -0
  42. data/app/views/user_notify/{monitoring_invitation_en.rhtml → monitoring_invitation.en.html.erb} +0 -0
  43. data/app/views/user_notify/{monitoring_invitation_no.rhtml → monitoring_invitation.no.html.erb} +0 -0
  44. data/app/views/user_notify/{signup_en.rhtml → signup.en.html.erb} +0 -0
  45. data/app/views/user_notify/{signup_no.rhtml → signup.no.html.erb} +0 -0
  46. data/app/views/work_lock_notify/{lock_en.rhtml → lock.en.html.erb} +0 -0
  47. data/app/views/work_lock_notify/{lock_no.rhtml → lock.no.html.erb} +0 -0
  48. data/app/views/work_lock_notify/{nag_en.rhtml → nag.en.html.erb} +0 -0
  49. data/app/views/work_lock_notify/{nag_no.rhtml → nag.no.html.erb} +0 -0
  50. data/app/views/works/_form.rhtml +6 -6
  51. data/app/views/works/_new_row.rhtml +6 -6
  52. data/app/views/works/_row.rhtml +2 -2
  53. data/app/views/works/daily_work_sheet.rhtml +1 -1
  54. data/app/views/works/list.rhtml +6 -6
  55. data/app/views/works/list_excel.rhtml +8 -4
  56. data/app/views/works/timeliste.rhtml +14 -14
  57. data/app/views/works/update_row.rjs +1 -1
  58. data/app/views/works/weekly_work_sheet.rhtml +5 -5
  59. data/app/views/works/weekly_work_sheet_details.rhtml +5 -5
  60. data/config/boot.rb +108 -27
  61. data/config/database.yml +3 -26
  62. data/config/environment.rb +4 -12
  63. data/config/environments/development.rb +0 -1
  64. data/config/initializers/jdbc.rb +7 -0
  65. data/config/initializers/mongrel.rb +83 -0
  66. data/config/locales/en.yml +189 -0
  67. data/config/locales/no.yml +192 -0
  68. data/config/preinitializer.rb +20 -0
  69. data/cruise_build.sh +10 -0
  70. data/cruise_config.rb +1 -1
  71. data/db/migrate/20100720124707_merge_work_account_into_backlog.rb +74 -0
  72. data/db/schema.rb +93 -127
  73. data/lib/class_table_inheritance.rb +53 -11
  74. data/lib/tasks/jdbc.rake +8 -0
  75. data/lib/user_system.rb +5 -1
  76. data/public/javascripts/controls.js +76 -79
  77. data/public/javascripts/dragdrop.js +166 -167
  78. data/public/javascripts/effects.js +174 -168
  79. data/public/javascripts/prototype.js +470 -334
  80. data/public/stylesheets/mwrt002.css +6 -6
  81. data/script/dbconsole +3 -0
  82. data/test/fixtures/backlogs.yml +2 -2
  83. data/test/fixtures/work_lock_subscriptions.yml +2 -2
  84. data/test/fixtures/works.yml +6 -6
  85. data/test/functional/absences_controller_test.rb +1 -1
  86. data/test/functional/backlogs_controller_test.rb +4 -4
  87. data/test/functional/customers_controller_test.rb +1 -1
  88. data/test/functional/dashboard_controller_test.rb +1 -1
  89. data/test/functional/estimates_controller_test.rb +1 -1
  90. data/test/functional/groups_controller_test.rb +1 -1
  91. data/test/functional/parties_controller_test.rb +1 -1
  92. data/test/functional/periods_controller_test.rb +1 -1
  93. data/test/functional/public_holidays_controller_test.rb +1 -1
  94. data/test/functional/search_controller_test.rb +1 -1
  95. data/test/functional/task_files_controller_test.rb +1 -1
  96. data/test/functional/tasks_controller_test.rb +6 -6
  97. data/test/functional/user_controller_test.rb +3 -2
  98. data/test/functional/welcome_controller_test.rb +1 -1
  99. data/test/functional/work_locks_controller_test.rb +1 -1
  100. data/test/functional/works_controller_test.rb +11 -11
  101. data/test/test_helper.rb +2 -2
  102. data/test/unit/absence_test.rb +1 -1
  103. data/test/unit/configuration_test.rb +1 -1
  104. data/test/unit/customer_test.rb +1 -1
  105. data/test/unit/estimate_test.rb +1 -1
  106. data/test/unit/group_test.rb +1 -1
  107. data/test/unit/party_test.rb +1 -1
  108. data/test/unit/period_test.rb +1 -1
  109. data/test/unit/public_holiday_test.rb +1 -1
  110. data/test/unit/task_file_test.rb +1 -1
  111. data/test/unit/task_test.rb +1 -1
  112. data/test/unit/user_test.rb +1 -1
  113. data/test/unit/work_lock_subscription_test.rb +1 -1
  114. data/test/unit/work_lock_test.rb +1 -1
  115. data/test/unit/work_test.rb +8 -8
  116. data/vendor/plugins/acts_as_list/lib/active_record/acts/list.rb +3 -3
  117. data/vendor/plugins/assert_cookie/lib/assert_cookie.rb +2 -2
  118. data/vendor/plugins/auto_complete/README +23 -0
  119. data/vendor/plugins/auto_complete/Rakefile +22 -0
  120. data/vendor/plugins/auto_complete/init.rb +2 -0
  121. data/vendor/plugins/auto_complete/lib/auto_complete.rb +47 -0
  122. data/vendor/plugins/auto_complete/lib/auto_complete_macros_helper.rb +143 -0
  123. data/vendor/plugins/auto_complete/test/auto_complete_test.rb +67 -0
  124. data/vendor/plugins/backlog_jira/init.rb +4 -0
  125. data/vendor/plugins/backlog_jira/{tasks → lib/tasks}/backlog_jira_tasks.rake +0 -0
  126. data/vendor/plugins/has_history/{tasks → lib/tasks}/has_history_tasks.rake +0 -0
  127. metadata +745 -817
  128. data/#SearchRequest.xml# +0 -3443
  129. data/app/controllers/application.rb~ +0 -207
  130. data/app/controllers/work_accounts_controller.rb +0 -58
  131. data/app/helpers/work_accounts_helper.rb +0 -2
  132. data/app/models/work_account.rb +0 -18
  133. data/app/models/work_lock_subscription.rb +0 -3
  134. data/app/views/work_accounts/_form.rhtml +0 -16
  135. data/app/views/work_accounts/_name_list.rhtml +0 -5
  136. data/app/views/work_accounts/_title.rhtml +0 -5
  137. data/app/views/work_accounts/edit.rhtml +0 -12
  138. data/app/views/work_accounts/list.rhtml +0 -31
  139. data/app/views/work_accounts/new.rhtml +0 -10
  140. data/app/views/work_accounts/show.rhtml +0 -50
  141. data/config/environments/localization_environment.rb +0 -10
  142. data/jira.log +0 -98246
  143. data/lang/en.yaml +0 -147
  144. data/lang/localizations.yaml +0 -2
  145. data/lang/no.yaml +0 -146
  146. data/lib/localization.rb +0 -88
  147. data/test/fixtures/work_accounts.yml +0 -7
  148. data/test/functional/work_accounts_controller_test.rb +0 -94
  149. data/test/unit/localization_test.rb +0 -47
  150. data/test/unit/work_account_test.rb +0 -10
@@ -1,8 +1,6 @@
1
- // script.aculo.us dragdrop.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
2
-
3
- // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
4
- // (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
5
- //
1
+ // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2
+ // (c) 2005-2008 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
3
+ //
6
4
  // script.aculo.us is freely distributable under the terms of an MIT-style license.
7
5
  // For details, see the script.aculo.us web site: http://script.aculo.us/
8
6
 
@@ -34,7 +32,7 @@ var Droppables = {
34
32
  options._containers.push($(containment));
35
33
  }
36
34
  }
37
-
35
+
38
36
  if(options.accept) options.accept = [options.accept].flatten();
39
37
 
40
38
  Element.makePositioned(element); // fix IE
@@ -42,34 +40,34 @@ var Droppables = {
42
40
 
43
41
  this.drops.push(options);
44
42
  },
45
-
43
+
46
44
  findDeepestChild: function(drops) {
47
45
  deepest = drops[0];
48
-
46
+
49
47
  for (i = 1; i < drops.length; ++i)
50
48
  if (Element.isParent(drops[i].element, deepest.element))
51
49
  deepest = drops[i];
52
-
50
+
53
51
  return deepest;
54
52
  },
55
53
 
56
54
  isContained: function(element, drop) {
57
55
  var containmentNode;
58
56
  if(drop.tree) {
59
- containmentNode = element.treeNode;
57
+ containmentNode = element.treeNode;
60
58
  } else {
61
59
  containmentNode = element.parentNode;
62
60
  }
63
61
  return drop._containers.detect(function(c) { return containmentNode == c });
64
62
  },
65
-
63
+
66
64
  isAffected: function(point, element, drop) {
67
65
  return (
68
66
  (drop.element!=element) &&
69
67
  ((!drop._containers) ||
70
68
  this.isContained(element, drop)) &&
71
69
  ((!drop.accept) ||
72
- (Element.classNames(element).detect(
70
+ (Element.classNames(element).detect(
73
71
  function(v) { return drop.accept.include(v) } ) )) &&
74
72
  Position.within(drop.element, point[0], point[1]) );
75
73
  },
@@ -89,12 +87,12 @@ var Droppables = {
89
87
  show: function(point, element) {
90
88
  if(!this.drops.length) return;
91
89
  var drop, affected = [];
92
-
90
+
93
91
  this.drops.each( function(drop) {
94
92
  if(Droppables.isAffected(point, element, drop))
95
93
  affected.push(drop);
96
94
  });
97
-
95
+
98
96
  if(affected.length>0)
99
97
  drop = Droppables.findDeepestChild(affected);
100
98
 
@@ -103,7 +101,7 @@ var Droppables = {
103
101
  Position.within(drop.element, point[0], point[1]);
104
102
  if(drop.onHover)
105
103
  drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
106
-
104
+
107
105
  if (drop != this.last_active) Droppables.activate(drop);
108
106
  }
109
107
  },
@@ -114,8 +112,8 @@ var Droppables = {
114
112
 
115
113
  if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
116
114
  if (this.last_active.onDrop) {
117
- this.last_active.onDrop(element, this.last_active.element, event);
118
- return true;
115
+ this.last_active.onDrop(element, this.last_active.element, event);
116
+ return true;
119
117
  }
120
118
  },
121
119
 
@@ -123,25 +121,25 @@ var Droppables = {
123
121
  if(this.last_active)
124
122
  this.deactivate(this.last_active);
125
123
  }
126
- }
124
+ };
127
125
 
128
126
  var Draggables = {
129
127
  drags: [],
130
128
  observers: [],
131
-
129
+
132
130
  register: function(draggable) {
133
131
  if(this.drags.length == 0) {
134
132
  this.eventMouseUp = this.endDrag.bindAsEventListener(this);
135
133
  this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
136
134
  this.eventKeypress = this.keyPress.bindAsEventListener(this);
137
-
135
+
138
136
  Event.observe(document, "mouseup", this.eventMouseUp);
139
137
  Event.observe(document, "mousemove", this.eventMouseMove);
140
138
  Event.observe(document, "keypress", this.eventKeypress);
141
139
  }
142
140
  this.drags.push(draggable);
143
141
  },
144
-
142
+
145
143
  unregister: function(draggable) {
146
144
  this.drags = this.drags.reject(function(d) { return d==draggable });
147
145
  if(this.drags.length == 0) {
@@ -150,24 +148,24 @@ var Draggables = {
150
148
  Event.stopObserving(document, "keypress", this.eventKeypress);
151
149
  }
152
150
  },
153
-
151
+
154
152
  activate: function(draggable) {
155
- if(draggable.options.delay) {
156
- this._timeout = setTimeout(function() {
157
- Draggables._timeout = null;
158
- window.focus();
159
- Draggables.activeDraggable = draggable;
160
- }.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);
161
159
  } else {
162
160
  window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
163
161
  this.activeDraggable = draggable;
164
162
  }
165
163
  },
166
-
164
+
167
165
  deactivate: function() {
168
166
  this.activeDraggable = null;
169
167
  },
170
-
168
+
171
169
  updateDrag: function(event) {
172
170
  if(!this.activeDraggable) return;
173
171
  var pointer = [Event.pointerX(event), Event.pointerY(event)];
@@ -175,36 +173,36 @@ var Draggables = {
175
173
  // the same coordinates, prevent needless redrawing (moz bug?)
176
174
  if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
177
175
  this._lastPointer = pointer;
178
-
176
+
179
177
  this.activeDraggable.updateDrag(event, pointer);
180
178
  },
181
-
179
+
182
180
  endDrag: function(event) {
183
- if(this._timeout) {
184
- clearTimeout(this._timeout);
185
- this._timeout = null;
181
+ if(this._timeout) {
182
+ clearTimeout(this._timeout);
183
+ this._timeout = null;
186
184
  }
187
185
  if(!this.activeDraggable) return;
188
186
  this._lastPointer = null;
189
187
  this.activeDraggable.endDrag(event);
190
188
  this.activeDraggable = null;
191
189
  },
192
-
190
+
193
191
  keyPress: function(event) {
194
192
  if(this.activeDraggable)
195
193
  this.activeDraggable.keyPress(event);
196
194
  },
197
-
195
+
198
196
  addObserver: function(observer) {
199
197
  this.observers.push(observer);
200
198
  this._cacheObserverCallbacks();
201
199
  },
202
-
200
+
203
201
  removeObserver: function(element) { // element instead of observer fixes mem leaks
204
202
  this.observers = this.observers.reject( function(o) { return o.element==element });
205
203
  this._cacheObserverCallbacks();
206
204
  },
207
-
205
+
208
206
  notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag'
209
207
  if(this[eventName+'Count'] > 0)
210
208
  this.observers.each( function(o) {
@@ -212,7 +210,7 @@ var Draggables = {
212
210
  });
213
211
  if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
214
212
  },
215
-
213
+
216
214
  _cacheObserverCallbacks: function() {
217
215
  ['onStart','onEnd','onDrag'].each( function(eventName) {
218
216
  Draggables[eventName+'Count'] = Draggables.observers.select(
@@ -220,7 +218,7 @@ var Draggables = {
220
218
  ).length;
221
219
  });
222
220
  }
223
- }
221
+ };
224
222
 
225
223
  /*--------------------------------------------------------------------------*/
226
224
 
@@ -236,12 +234,12 @@ var Draggable = Class.create({
236
234
  },
237
235
  endeffect: function(element) {
238
236
  var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0;
239
- 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,
240
238
  queue: {scope:'_draggable', position:'end'},
241
- afterFinish: function(){
242
- Draggable._dragging[element] = false
239
+ afterFinish: function(){
240
+ Draggable._dragging[element] = false
243
241
  }
244
- });
242
+ });
245
243
  },
246
244
  zindex: 1000,
247
245
  revert: false,
@@ -252,57 +250,57 @@ var Draggable = Class.create({
252
250
  snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] }
253
251
  delay: 0
254
252
  };
255
-
253
+
256
254
  if(!arguments[1] || Object.isUndefined(arguments[1].endeffect))
257
255
  Object.extend(defaults, {
258
256
  starteffect: function(element) {
259
257
  element._opacity = Element.getOpacity(element);
260
258
  Draggable._dragging[element] = true;
261
- 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});
262
260
  }
263
261
  });
264
-
262
+
265
263
  var options = Object.extend(defaults, arguments[1] || { });
266
264
 
267
265
  this.element = $(element);
268
-
266
+
269
267
  if(options.handle && Object.isString(options.handle))
270
268
  this.handle = this.element.down('.'+options.handle, 0);
271
-
269
+
272
270
  if(!this.handle) this.handle = $(options.handle);
273
271
  if(!this.handle) this.handle = this.element;
274
-
272
+
275
273
  if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
276
274
  options.scroll = $(options.scroll);
277
275
  this._isScrollChild = Element.childOf(this.element, options.scroll);
278
276
  }
279
277
 
280
- Element.makePositioned(this.element); // fix IE
278
+ Element.makePositioned(this.element); // fix IE
281
279
 
282
280
  this.options = options;
283
- this.dragging = false;
281
+ this.dragging = false;
284
282
 
285
283
  this.eventMouseDown = this.initDrag.bindAsEventListener(this);
286
284
  Event.observe(this.handle, "mousedown", this.eventMouseDown);
287
-
285
+
288
286
  Draggables.register(this);
289
287
  },
290
-
288
+
291
289
  destroy: function() {
292
290
  Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
293
291
  Draggables.unregister(this);
294
292
  },
295
-
293
+
296
294
  currentDelta: function() {
297
295
  return([
298
296
  parseInt(Element.getStyle(this.element,'left') || '0'),
299
297
  parseInt(Element.getStyle(this.element,'top') || '0')]);
300
298
  },
301
-
299
+
302
300
  initDrag: function(event) {
303
301
  if(!Object.isUndefined(Draggable._dragging[this.element]) &&
304
302
  Draggable._dragging[this.element]) return;
305
- if(Event.isLeftClick(event)) {
303
+ if(Event.isLeftClick(event)) {
306
304
  // abort on form elements, fixes a Firefox issue
307
305
  var src = Event.element(event);
308
306
  if((tag_name = src.tagName.toUpperCase()) && (
@@ -311,34 +309,34 @@ var Draggable = Class.create({
311
309
  tag_name=='OPTION' ||
312
310
  tag_name=='BUTTON' ||
313
311
  tag_name=='TEXTAREA')) return;
314
-
312
+
315
313
  var pointer = [Event.pointerX(event), Event.pointerY(event)];
316
314
  var pos = Position.cumulativeOffset(this.element);
317
315
  this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
318
-
316
+
319
317
  Draggables.activate(this);
320
318
  Event.stop(event);
321
319
  }
322
320
  },
323
-
321
+
324
322
  startDrag: function(event) {
325
323
  this.dragging = true;
326
324
  if(!this.delta)
327
325
  this.delta = this.currentDelta();
328
-
326
+
329
327
  if(this.options.zindex) {
330
328
  this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
331
329
  this.element.style.zIndex = this.options.zindex;
332
330
  }
333
-
331
+
334
332
  if(this.options.ghosting) {
335
333
  this._clone = this.element.cloneNode(true);
336
- this.element._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
337
- if (!this.element._originallyAbsolute)
334
+ this._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
335
+ if (!this._originallyAbsolute)
338
336
  Position.absolutize(this.element);
339
337
  this.element.parentNode.insertBefore(this._clone, this.element);
340
338
  }
341
-
339
+
342
340
  if(this.options.scroll) {
343
341
  if (this.options.scroll == window) {
344
342
  var where = this._getWindowScroll(this.options.scroll);
@@ -349,28 +347,28 @@ var Draggable = Class.create({
349
347
  this.originalScrollTop = this.options.scroll.scrollTop;
350
348
  }
351
349
  }
352
-
350
+
353
351
  Draggables.notify('onStart', this, event);
354
-
352
+
355
353
  if(this.options.starteffect) this.options.starteffect(this.element);
356
354
  },
357
-
355
+
358
356
  updateDrag: function(event, pointer) {
359
357
  if(!this.dragging) this.startDrag(event);
360
-
358
+
361
359
  if(!this.options.quiet){
362
360
  Position.prepare();
363
361
  Droppables.show(pointer, this.element);
364
362
  }
365
-
363
+
366
364
  Draggables.notify('onDrag', this, event);
367
-
365
+
368
366
  this.draw(pointer);
369
367
  if(this.options.change) this.options.change(this);
370
-
368
+
371
369
  if(this.options.scroll) {
372
370
  this.stopScrolling();
373
-
371
+
374
372
  var p;
375
373
  if (this.options.scroll == window) {
376
374
  with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
@@ -388,16 +386,16 @@ var Draggable = Class.create({
388
386
  if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
389
387
  this.startScrolling(speed);
390
388
  }
391
-
389
+
392
390
  // fix AppleWebKit rendering
393
391
  if(Prototype.Browser.WebKit) window.scrollBy(0,0);
394
-
392
+
395
393
  Event.stop(event);
396
394
  },
397
-
395
+
398
396
  finishDrag: function(event, success) {
399
397
  this.dragging = false;
400
-
398
+
401
399
  if(this.options.quiet){
402
400
  Position.prepare();
403
401
  var pointer = [Event.pointerX(event), Event.pointerY(event)];
@@ -405,24 +403,24 @@ var Draggable = Class.create({
405
403
  }
406
404
 
407
405
  if(this.options.ghosting) {
408
- if (!this.element._originallyAbsolute)
406
+ if (!this._originallyAbsolute)
409
407
  Position.relativize(this.element);
410
- delete this.element._originallyAbsolute;
408
+ delete this._originallyAbsolute;
411
409
  Element.remove(this._clone);
412
410
  this._clone = null;
413
411
  }
414
412
 
415
- var dropped = false;
416
- if(success) {
417
- dropped = Droppables.fire(event, this.element);
418
- if (!dropped) dropped = false;
413
+ var dropped = false;
414
+ if(success) {
415
+ dropped = Droppables.fire(event, this.element);
416
+ if (!dropped) dropped = false;
419
417
  }
420
418
  if(dropped && this.options.onDropped) this.options.onDropped(this.element);
421
419
  Draggables.notify('onEnd', this, event);
422
420
 
423
421
  var revert = this.options.revert;
424
422
  if(revert && Object.isFunction(revert)) revert = revert(this.element);
425
-
423
+
426
424
  var d = this.currentDelta();
427
425
  if(revert && this.options.reverteffect) {
428
426
  if (dropped == 0 || revert != 'failure')
@@ -435,67 +433,67 @@ var Draggable = Class.create({
435
433
  if(this.options.zindex)
436
434
  this.element.style.zIndex = this.originalZ;
437
435
 
438
- if(this.options.endeffect)
436
+ if(this.options.endeffect)
439
437
  this.options.endeffect(this.element);
440
-
438
+
441
439
  Draggables.deactivate(this);
442
440
  Droppables.reset();
443
441
  },
444
-
442
+
445
443
  keyPress: function(event) {
446
444
  if(event.keyCode!=Event.KEY_ESC) return;
447
445
  this.finishDrag(event, false);
448
446
  Event.stop(event);
449
447
  },
450
-
448
+
451
449
  endDrag: function(event) {
452
450
  if(!this.dragging) return;
453
451
  this.stopScrolling();
454
452
  this.finishDrag(event, true);
455
453
  Event.stop(event);
456
454
  },
457
-
455
+
458
456
  draw: function(point) {
459
457
  var pos = Position.cumulativeOffset(this.element);
460
458
  if(this.options.ghosting) {
461
459
  var r = Position.realOffset(this.element);
462
460
  pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
463
461
  }
464
-
462
+
465
463
  var d = this.currentDelta();
466
464
  pos[0] -= d[0]; pos[1] -= d[1];
467
-
465
+
468
466
  if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
469
467
  pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
470
468
  pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
471
469
  }
472
-
473
- var p = [0,1].map(function(i){
474
- 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])
475
473
  }.bind(this));
476
-
474
+
477
475
  if(this.options.snap) {
478
476
  if(Object.isFunction(this.options.snap)) {
479
477
  p = this.options.snap(p[0],p[1],this);
480
478
  } else {
481
479
  if(Object.isArray(this.options.snap)) {
482
480
  p = p.map( function(v, i) {
483
- 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));
484
482
  } else {
485
483
  p = p.map( function(v) {
486
- return (v/this.options.snap).round()*this.options.snap }.bind(this))
484
+ return (v/this.options.snap).round()*this.options.snap }.bind(this));
487
485
  }
488
486
  }}
489
-
487
+
490
488
  var style = this.element.style;
491
489
  if((!this.options.constraint) || (this.options.constraint=='horizontal'))
492
490
  style.left = p[0] + "px";
493
491
  if((!this.options.constraint) || (this.options.constraint=='vertical'))
494
492
  style.top = p[1] + "px";
495
-
493
+
496
494
  if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
497
495
  },
498
-
496
+
499
497
  stopScrolling: function() {
500
498
  if(this.scrollInterval) {
501
499
  clearInterval(this.scrollInterval);
@@ -503,14 +501,14 @@ var Draggable = Class.create({
503
501
  Draggables._lastScrollPointer = null;
504
502
  }
505
503
  },
506
-
504
+
507
505
  startScrolling: function(speed) {
508
506
  if(!(speed[0] || speed[1])) return;
509
507
  this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
510
508
  this.lastScrolled = new Date();
511
509
  this.scrollInterval = setInterval(this.scroll.bind(this), 10);
512
510
  },
513
-
511
+
514
512
  scroll: function() {
515
513
  var current = new Date();
516
514
  var delta = current - this.lastScrolled;
@@ -526,7 +524,7 @@ var Draggable = Class.create({
526
524
  this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
527
525
  this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
528
526
  }
529
-
527
+
530
528
  Position.prepare();
531
529
  Droppables.show(Draggables._lastPointer, this.element);
532
530
  Draggables.notify('onDrag', this);
@@ -540,10 +538,10 @@ var Draggable = Class.create({
540
538
  Draggables._lastScrollPointer[1] = 0;
541
539
  this.draw(Draggables._lastScrollPointer);
542
540
  }
543
-
541
+
544
542
  if(this.options.change) this.options.change(this);
545
543
  },
546
-
544
+
547
545
  _getWindowScroll: function(w) {
548
546
  var T, L, W, H;
549
547
  with (w.document) {
@@ -562,7 +560,7 @@ var Draggable = Class.create({
562
560
  H = documentElement.clientHeight;
563
561
  } else {
564
562
  W = body.offsetWidth;
565
- H = body.offsetHeight
563
+ H = body.offsetHeight;
566
564
  }
567
565
  }
568
566
  return { top: T, left: L, width: W, height: H };
@@ -579,11 +577,11 @@ var SortableObserver = Class.create({
579
577
  this.observer = observer;
580
578
  this.lastValue = Sortable.serialize(this.element);
581
579
  },
582
-
580
+
583
581
  onStart: function() {
584
582
  this.lastValue = Sortable.serialize(this.element);
585
583
  },
586
-
584
+
587
585
  onEnd: function() {
588
586
  Sortable.unmark();
589
587
  if(this.lastValue != Sortable.serialize(this.element))
@@ -593,11 +591,11 @@ var SortableObserver = Class.create({
593
591
 
594
592
  var Sortable = {
595
593
  SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
596
-
594
+
597
595
  sortables: { },
598
-
596
+
599
597
  _findRootElement: function(element) {
600
- while (element.tagName.toUpperCase() != "BODY") {
598
+ while (element.tagName.toUpperCase() != "BODY") {
601
599
  if(element.id && Sortable.sortables[element.id]) return element;
602
600
  element = element.parentNode;
603
601
  }
@@ -608,22 +606,23 @@ var Sortable = {
608
606
  if(!element) return;
609
607
  return Sortable.sortables[element.id];
610
608
  },
611
-
609
+
612
610
  destroy: function(element){
613
- var s = Sortable.options(element);
614
-
611
+ element = $(element);
612
+ var s = Sortable.sortables[element.id];
613
+
615
614
  if(s) {
616
615
  Draggables.removeObserver(s.element);
617
616
  s.droppables.each(function(d){ Droppables.remove(d) });
618
617
  s.draggables.invoke('destroy');
619
-
618
+
620
619
  delete Sortable.sortables[s.element.id];
621
620
  }
622
621
  },
623
622
 
624
623
  create: function(element) {
625
624
  element = $(element);
626
- var options = Object.extend({
625
+ var options = Object.extend({
627
626
  element: element,
628
627
  tag: 'li', // assumes li children, override with tag: 'tagname'
629
628
  dropOnEmpty: false,
@@ -637,17 +636,17 @@ var Sortable = {
637
636
  delay: 0,
638
637
  hoverclass: null,
639
638
  ghosting: false,
640
- quiet: false,
639
+ quiet: false,
641
640
  scroll: false,
642
641
  scrollSensitivity: 20,
643
642
  scrollSpeed: 15,
644
643
  format: this.SERIALIZE_RULE,
645
-
646
- // these take arrays of elements or ids and can be
644
+
645
+ // these take arrays of elements or ids and can be
647
646
  // used for better initialization performance
648
647
  elements: false,
649
648
  handles: false,
650
-
649
+
651
650
  onChange: Prototype.emptyFunction,
652
651
  onUpdate: Prototype.emptyFunction
653
652
  }, arguments[1] || { });
@@ -684,24 +683,24 @@ var Sortable = {
684
683
  if(options.zindex)
685
684
  options_for_draggable.zindex = options.zindex;
686
685
 
687
- // build options for the droppables
686
+ // build options for the droppables
688
687
  var options_for_droppable = {
689
688
  overlap: options.overlap,
690
689
  containment: options.containment,
691
690
  tree: options.tree,
692
691
  hoverclass: options.hoverclass,
693
692
  onHover: Sortable.onHover
694
- }
695
-
693
+ };
694
+
696
695
  var options_for_tree = {
697
696
  onHover: Sortable.onEmptyHover,
698
697
  overlap: options.overlap,
699
698
  containment: options.containment,
700
699
  hoverclass: options.hoverclass
701
- }
700
+ };
702
701
 
703
702
  // fix for gecko engine
704
- Element.cleanWhitespace(element);
703
+ Element.cleanWhitespace(element);
705
704
 
706
705
  options.draggables = [];
707
706
  options.droppables = [];
@@ -714,14 +713,14 @@ var Sortable = {
714
713
 
715
714
  (options.elements || this.findElements(element, options) || []).each( function(e,i) {
716
715
  var handle = options.handles ? $(options.handles[i]) :
717
- (options.handle ? $(e).select('.' + options.handle)[0] : e);
716
+ (options.handle ? $(e).select('.' + options.handle)[0] : e);
718
717
  options.draggables.push(
719
718
  new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
720
719
  Droppables.add(e, options_for_droppable);
721
720
  if(options.tree) e.treeNode = element;
722
- options.droppables.push(e);
721
+ options.droppables.push(e);
723
722
  });
724
-
723
+
725
724
  if(options.tree) {
726
725
  (Sortable.findTreeElements(element, options) || []).each( function(e) {
727
726
  Droppables.add(e, options_for_tree);
@@ -743,7 +742,7 @@ var Sortable = {
743
742
  return Element.findChildren(
744
743
  element, options.only, options.tree ? true : false, options.tag);
745
744
  },
746
-
745
+
747
746
  findTreeElements: function(element, options) {
748
747
  return Element.findChildren(
749
748
  element, options.only, options.tree ? true : false, options.treeTag);
@@ -760,7 +759,7 @@ var Sortable = {
760
759
  var oldParentNode = element.parentNode;
761
760
  element.style.visibility = "hidden"; // fix gecko rendering
762
761
  dropon.parentNode.insertBefore(element, dropon);
763
- if(dropon.parentNode!=oldParentNode)
762
+ if(dropon.parentNode!=oldParentNode)
764
763
  Sortable.options(oldParentNode).onChange(element);
765
764
  Sortable.options(dropon.parentNode).onChange(element);
766
765
  }
@@ -771,26 +770,26 @@ var Sortable = {
771
770
  var oldParentNode = element.parentNode;
772
771
  element.style.visibility = "hidden"; // fix gecko rendering
773
772
  dropon.parentNode.insertBefore(element, nextElement);
774
- if(dropon.parentNode!=oldParentNode)
773
+ if(dropon.parentNode!=oldParentNode)
775
774
  Sortable.options(oldParentNode).onChange(element);
776
775
  Sortable.options(dropon.parentNode).onChange(element);
777
776
  }
778
777
  }
779
778
  },
780
-
779
+
781
780
  onEmptyHover: function(element, dropon, overlap) {
782
781
  var oldParentNode = element.parentNode;
783
782
  var droponOptions = Sortable.options(dropon);
784
-
783
+
785
784
  if(!Element.isParent(dropon, element)) {
786
785
  var index;
787
-
786
+
788
787
  var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
789
788
  var child = null;
790
-
789
+
791
790
  if(children) {
792
791
  var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
793
-
792
+
794
793
  for (index = 0; index < children.length; index += 1) {
795
794
  if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
796
795
  offset -= Element.offsetSize (children[index], droponOptions.overlap);
@@ -803,9 +802,9 @@ var Sortable = {
803
802
  }
804
803
  }
805
804
  }
806
-
805
+
807
806
  dropon.insertBefore(element, child);
808
-
807
+
809
808
  Sortable.options(oldParentNode).onChange(element);
810
809
  droponOptions.onChange(element);
811
810
  }
@@ -818,34 +817,34 @@ var Sortable = {
818
817
  mark: function(dropon, position) {
819
818
  // mark on ghosting only
820
819
  var sortable = Sortable.options(dropon.parentNode);
821
- if(sortable && !sortable.ghosting) return;
820
+ if(sortable && !sortable.ghosting) return;
822
821
 
823
822
  if(!Sortable._marker) {
824
- Sortable._marker =
823
+ Sortable._marker =
825
824
  ($('dropmarker') || Element.extend(document.createElement('DIV'))).
826
825
  hide().addClassName('dropmarker').setStyle({position:'absolute'});
827
826
  document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
828
- }
827
+ }
829
828
  var offsets = Position.cumulativeOffset(dropon);
830
829
  Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
831
-
830
+
832
831
  if(position=='after')
833
- if(sortable.overlap == 'horizontal')
832
+ if(sortable.overlap == 'horizontal')
834
833
  Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
835
834
  else
836
835
  Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
837
-
836
+
838
837
  Sortable._marker.show();
839
838
  },
840
-
839
+
841
840
  _tree: function(element, options, parent) {
842
841
  var children = Sortable.findElements(element, options) || [];
843
-
842
+
844
843
  for (var i = 0; i < children.length; ++i) {
845
844
  var match = children[i].id.match(options.format);
846
845
 
847
846
  if (!match) continue;
848
-
847
+
849
848
  var child = {
850
849
  id: encodeURIComponent(match ? match[1] : null),
851
850
  element: element,
@@ -853,16 +852,16 @@ var Sortable = {
853
852
  children: [],
854
853
  position: parent.children.length,
855
854
  container: $(children[i]).down(options.treeTag)
856
- }
857
-
855
+ };
856
+
858
857
  /* Get the element containing the children and recurse over it */
859
858
  if (child.container)
860
- this._tree(child.container, options, child)
861
-
859
+ this._tree(child.container, options, child);
860
+
862
861
  parent.children.push (child);
863
862
  }
864
863
 
865
- return parent;
864
+ return parent;
866
865
  },
867
866
 
868
867
  tree: function(element) {
@@ -875,15 +874,15 @@ var Sortable = {
875
874
  name: element.id,
876
875
  format: sortableOptions.format
877
876
  }, arguments[1] || { });
878
-
877
+
879
878
  var root = {
880
879
  id: null,
881
880
  parent: null,
882
881
  children: [],
883
882
  container: element,
884
883
  position: 0
885
- }
886
-
884
+ };
885
+
887
886
  return Sortable._tree(element, options, root);
888
887
  },
889
888
 
@@ -899,7 +898,7 @@ var Sortable = {
899
898
  sequence: function(element) {
900
899
  element = $(element);
901
900
  var options = Object.extend(this.options(element), arguments[1] || { });
902
-
901
+
903
902
  return $(this.findElements(element, options) || []).map( function(item) {
904
903
  return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
905
904
  });
@@ -908,14 +907,14 @@ var Sortable = {
908
907
  setSequence: function(element, new_sequence) {
909
908
  element = $(element);
910
909
  var options = Object.extend(this.options(element), arguments[2] || { });
911
-
910
+
912
911
  var nodeMap = { };
913
912
  this.findElements(element, options).each( function(n) {
914
913
  if (n.id.match(options.format))
915
914
  nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
916
915
  n.parentNode.removeChild(n);
917
916
  });
918
-
917
+
919
918
  new_sequence.each(function(ident) {
920
919
  var n = nodeMap[ident];
921
920
  if (n) {
@@ -924,16 +923,16 @@ var Sortable = {
924
923
  }
925
924
  });
926
925
  },
927
-
926
+
928
927
  serialize: function(element) {
929
928
  element = $(element);
930
929
  var options = Object.extend(Sortable.options(element), arguments[1] || { });
931
930
  var name = encodeURIComponent(
932
931
  (arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
933
-
932
+
934
933
  if (options.tree) {
935
934
  return Sortable.tree(element, arguments[1]).children.map( function (item) {
936
- return [name + Sortable._constructIndex(item) + "[id]=" +
935
+ return [name + Sortable._constructIndex(item) + "[id]=" +
937
936
  encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
938
937
  }).flatten().join('&');
939
938
  } else {
@@ -942,16 +941,16 @@ var Sortable = {
942
941
  }).join('&');
943
942
  }
944
943
  }
945
- }
944
+ };
946
945
 
947
946
  // Returns true if child is contained within element
948
947
  Element.isParent = function(child, element) {
949
948
  if (!child.parentNode || child == element) return false;
950
949
  if (child.parentNode == element) return true;
951
950
  return Element.isParent(child.parentNode, element);
952
- }
951
+ };
953
952
 
954
- Element.findChildren = function(element, only, recursive, tagName) {
953
+ Element.findChildren = function(element, only, recursive, tagName) {
955
954
  if(!element.hasChildNodes()) return null;
956
955
  tagName = tagName.toUpperCase();
957
956
  if(only) only = [only].flatten();
@@ -967,8 +966,8 @@ Element.findChildren = function(element, only, recursive, tagName) {
967
966
  });
968
967
 
969
968
  return (elements.length>0 ? elements.flatten() : []);
970
- }
969
+ };
971
970
 
972
971
  Element.offsetSize = function (element, type) {
973
972
  return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
974
- }
973
+ };