summaryrefslogtreecommitdiff
path: root/frontend/gamma/js/MochiKit/DragAndDrop.js
authorGiulio Cesare Solaroli <giulio.cesare@clipperz.com>2011-10-02 23:56:18 (UTC)
committer Giulio Cesare Solaroli <giulio.cesare@clipperz.com>2011-10-02 23:56:18 (UTC)
commitef68436ac04da078ffdcacd7e1f785473a303d45 (patch) (unidiff)
treec403752d66a2c4775f00affd4fa8431b29c5b68c /frontend/gamma/js/MochiKit/DragAndDrop.js
parent597ecfbc0249d83e1b856cbd558340c01237a360 (diff)
downloadclipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.zip
clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.gz
clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.bz2
First version of the newly restructured repository
Diffstat (limited to 'frontend/gamma/js/MochiKit/DragAndDrop.js') (more/less context) (show whitespace changes)
-rw-r--r--frontend/gamma/js/MochiKit/DragAndDrop.js766
1 files changed, 766 insertions, 0 deletions
diff --git a/frontend/gamma/js/MochiKit/DragAndDrop.js b/frontend/gamma/js/MochiKit/DragAndDrop.js
new file mode 100644
index 0000000..62777c5
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/DragAndDrop.js
@@ -0,0 +1,766 @@
1/***
2MochiKit.DragAndDrop 1.5
3
4See <http://mochikit.com/> for documentation, downloads, license, etc.
5
6Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
7 Mochi-ized By Thomas Herve (_firstname_@nimail.org)
8
9***/
10
11MochiKit.Base._module('DragAndDrop', '1.5', ['Base', 'Iter', 'DOM', 'Signal', 'Visual', 'Position']);
12
13MochiKit.DragAndDrop.Droppables = {
14 /***
15
16 Manage all droppables. Shouldn't be used, use the Droppable object instead.
17
18 ***/
19 drops: [],
20
21 remove: function (element) {
22 this.drops = MochiKit.Base.filter(function (d) {
23 return d.element != MochiKit.DOM.getElement(element);
24 }, this.drops);
25 },
26
27 register: function (drop) {
28 this.drops.push(drop);
29 },
30
31 unregister: function (drop) {
32 this.drops = MochiKit.Base.filter(function (d) {
33 return d != drop;
34 }, this.drops);
35 },
36
37 prepare: function (element) {
38 MochiKit.Base.map(function (drop) {
39 if (drop.isAccepted(element)) {
40 if (drop.options.activeclass) {
41 MochiKit.DOM.addElementClass(drop.element,
42 drop.options.activeclass);
43 }
44 drop.options.onactive(drop.element, element);
45 }
46 }, this.drops);
47 },
48
49 findDeepestChild: function (drops) {
50 var deepest = drops[0];
51
52 for (var i = 1; i < drops.length; ++i) {
53 if (MochiKit.DOM.isChildNode(drops[i].element, deepest.element)) {
54 deepest = drops[i];
55 }
56 }
57 return deepest;
58 },
59
60 show: function (point, element) {
61 if (!this.drops.length) {
62 return;
63 }
64 var affected = [];
65
66 if (this.last_active) {
67 this.last_active.deactivate();
68 }
69 MochiKit.Iter.forEach(this.drops, function (drop) {
70 if (drop.isAffected(point, element)) {
71 affected.push(drop);
72 }
73 });
74 if (affected.length > 0) {
75 var drop = this.findDeepestChild(affected);
76 MochiKit.Position.within(drop.element, point.page.x, point.page.y);
77 drop.options.onhover(element, drop.element,
78 MochiKit.Position.overlap(drop.options.overlap, drop.element));
79 drop.activate();
80 }
81 },
82
83 fire: function (event, element) {
84 if (!this.last_active) {
85 return;
86 }
87 MochiKit.Position.prepare();
88
89 if (this.last_active.isAffected(event.mouse(), element)) {
90 this.last_active.options.ondrop(element,
91 this.last_active.element, event);
92 }
93 },
94
95 reset: function (element) {
96 MochiKit.Base.map(function (drop) {
97 if (drop.options.activeclass) {
98 MochiKit.DOM.removeElementClass(drop.element,
99 drop.options.activeclass);
100 }
101 drop.options.ondesactive(drop.element, element);
102 }, this.drops);
103 if (this.last_active) {
104 this.last_active.deactivate();
105 }
106 }
107};
108
109/** @id MochiKit.DragAndDrop.Droppable */
110MochiKit.DragAndDrop.Droppable = function (element, options) {
111 var cls = arguments.callee;
112 if (!(this instanceof cls)) {
113 return new cls(element, options);
114 }
115 this.__init__(element, options);
116};
117
118MochiKit.DragAndDrop.Droppable.prototype = {
119 /***
120
121 A droppable object. Simple use is to create giving an element:
122
123 new MochiKit.DragAndDrop.Droppable('myelement');
124
125 Generally you'll want to define the 'ondrop' function and maybe the
126 'accept' option to filter draggables.
127
128 ***/
129 __class__: MochiKit.DragAndDrop.Droppable,
130
131 __init__: function (element, /* optional */options) {
132 var d = MochiKit.DOM;
133 var b = MochiKit.Base;
134 this.element = d.getElement(element);
135 this.options = b.update({
136
137 /** @id MochiKit.DragAndDrop.greedy */
138 greedy: true,
139
140 /** @id MochiKit.DragAndDrop.hoverclass */
141 hoverclass: null,
142
143 /** @id MochiKit.DragAndDrop.activeclass */
144 activeclass: null,
145
146 /** @id MochiKit.DragAndDrop.hoverfunc */
147 hoverfunc: b.noop,
148
149 /** @id MochiKit.DragAndDrop.accept */
150 accept: null,
151
152 /** @id MochiKit.DragAndDrop.onactive */
153 onactive: b.noop,
154
155 /** @id MochiKit.DragAndDrop.ondesactive */
156 ondesactive: b.noop,
157
158 /** @id MochiKit.DragAndDrop.onhover */
159 onhover: b.noop,
160
161 /** @id MochiKit.DragAndDrop.ondrop */
162 ondrop: b.noop,
163
164 /** @id MochiKit.DragAndDrop.containment */
165 containment: [],
166 tree: false
167 }, options);
168
169 // cache containers
170 this.options._containers = [];
171 b.map(MochiKit.Base.bind(function (c) {
172 this.options._containers.push(d.getElement(c));
173 }, this), this.options.containment);
174
175 MochiKit.Style.makePositioned(this.element); // fix IE
176
177 MochiKit.DragAndDrop.Droppables.register(this);
178 },
179
180 /** @id MochiKit.DragAndDrop.isContained */
181 isContained: function (element) {
182 if (this.options._containers.length) {
183 var containmentNode;
184 if (this.options.tree) {
185 containmentNode = element.treeNode;
186 } else {
187 containmentNode = element.parentNode;
188 }
189 return MochiKit.Iter.some(this.options._containers, function (c) {
190 return containmentNode == c;
191 });
192 } else {
193 return true;
194 }
195 },
196
197 /** @id MochiKit.DragAndDrop.isAccepted */
198 isAccepted: function (element) {
199 return ((!this.options.accept) || MochiKit.Iter.some(
200 this.options.accept, function (c) {
201 return MochiKit.DOM.hasElementClass(element, c);
202 }));
203 },
204
205 /** @id MochiKit.DragAndDrop.isAffected */
206 isAffected: function (point, element) {
207 return ((this.element != element) &&
208 this.isContained(element) &&
209 this.isAccepted(element) &&
210 MochiKit.Position.within(this.element, point.page.x,
211 point.page.y));
212 },
213
214 /** @id MochiKit.DragAndDrop.deactivate */
215 deactivate: function () {
216 /***
217
218 A droppable is deactivate when a draggable has been over it and left.
219
220 ***/
221 if (this.options.hoverclass) {
222 MochiKit.DOM.removeElementClass(this.element,
223 this.options.hoverclass);
224 }
225 this.options.hoverfunc(this.element, false);
226 MochiKit.DragAndDrop.Droppables.last_active = null;
227 },
228
229 /** @id MochiKit.DragAndDrop.activate */
230 activate: function () {
231 /***
232
233 A droppable is active when a draggable is over it.
234
235 ***/
236 if (this.options.hoverclass) {
237 MochiKit.DOM.addElementClass(this.element, this.options.hoverclass);
238 }
239 this.options.hoverfunc(this.element, true);
240 MochiKit.DragAndDrop.Droppables.last_active = this;
241 },
242
243 /** @id MochiKit.DragAndDrop.destroy */
244 destroy: function () {
245 /***
246
247 Delete this droppable.
248
249 ***/
250 MochiKit.DragAndDrop.Droppables.unregister(this);
251 },
252
253 /** @id MochiKit.DragAndDrop.repr */
254 repr: function () {
255 return '[' + this.__class__.NAME + ", options:" + MochiKit.Base.repr(this.options) + "]";
256 }
257};
258
259MochiKit.DragAndDrop.Draggables = {
260 /***
261
262 Manage draggables elements. Not intended to direct use.
263
264 ***/
265 drags: [],
266
267 register: function (draggable) {
268 if (this.drags.length === 0) {
269 var conn = MochiKit.Signal.connect;
270 this.eventMouseUp = conn(document, 'onmouseup', this, this.endDrag);
271 this.eventMouseMove = conn(document, 'onmousemove', this,
272 this.updateDrag);
273 this.eventKeypress = conn(document, 'onkeypress', this,
274 this.keyPress);
275 }
276 this.drags.push(draggable);
277 },
278
279 unregister: function (draggable) {
280 this.drags = MochiKit.Base.filter(function (d) {
281 return d != draggable;
282 }, this.drags);
283 if (this.drags.length === 0) {
284 var disc = MochiKit.Signal.disconnect;
285 disc(this.eventMouseUp);
286 disc(this.eventMouseMove);
287 disc(this.eventKeypress);
288 }
289 },
290
291 activate: function (draggable) {
292 // allows keypress events if window is not currently focused
293 // fails for Safari
294 window.focus();
295 this.activeDraggable = draggable;
296 },
297
298 deactivate: function () {
299 this.activeDraggable = null;
300 },
301
302 updateDrag: function (event) {
303 if (!this.activeDraggable) {
304 return;
305 }
306 var pointer = event.mouse();
307 // Mozilla-based browsers fire successive mousemove events with
308 // the same coordinates, prevent needless redrawing (moz bug?)
309 if (this._lastPointer && (MochiKit.Base.repr(this._lastPointer.page) ==
310 MochiKit.Base.repr(pointer.page))) {
311 return;
312 }
313 this._lastPointer = pointer;
314 this.activeDraggable.updateDrag(event, pointer);
315 },
316
317 endDrag: function (event) {
318 if (!this.activeDraggable) {
319 return;
320 }
321 this._lastPointer = null;
322 this.activeDraggable.endDrag(event);
323 this.activeDraggable = null;
324 },
325
326 keyPress: function (event) {
327 if (this.activeDraggable) {
328 this.activeDraggable.keyPress(event);
329 }
330 },
331
332 notify: function (eventName, draggable, event) {
333 MochiKit.Signal.signal(this, eventName, draggable, event);
334 }
335};
336
337/** @id MochiKit.DragAndDrop.Draggable */
338MochiKit.DragAndDrop.Draggable = function (element, options) {
339 var cls = arguments.callee;
340 if (!(this instanceof cls)) {
341 return new cls(element, options);
342 }
343 this.__init__(element, options);
344};
345
346MochiKit.DragAndDrop.Draggable.prototype = {
347 /***
348
349 A draggable object. Simple instantiate :
350
351 new MochiKit.DragAndDrop.Draggable('myelement');
352
353 ***/
354 __class__ : MochiKit.DragAndDrop.Draggable,
355
356 __init__: function (element, /* optional */options) {
357 var v = MochiKit.Visual;
358 var b = MochiKit.Base;
359 options = b.update({
360
361 /** @id MochiKit.DragAndDrop.handle */
362 handle: false,
363
364 /** @id MochiKit.DragAndDrop.starteffect */
365 starteffect: function (innerelement) {
366 this._savedOpacity = MochiKit.Style.getStyle(innerelement, 'opacity') || 1.0;
367 new v.Opacity(innerelement, {duration:0.2, from:this._savedOpacity, to:0.7});
368 },
369 /** @id MochiKit.DragAndDrop.reverteffect */
370 reverteffect: function (innerelement, top_offset, left_offset) {
371 var dur = Math.sqrt(Math.abs(top_offset^2) +
372 Math.abs(left_offset^2))*0.02;
373 return new v.Move(innerelement,
374 {x: -left_offset, y: -top_offset, duration: dur});
375 },
376
377 /** @id MochiKit.DragAndDrop.endeffect */
378 endeffect: function (innerelement) {
379 new v.Opacity(innerelement, {duration:0.2, from:0.7, to:this._savedOpacity});
380 },
381
382 /** @id MochiKit.DragAndDrop.onchange */
383 onchange: b.noop,
384
385 /** @id MochiKit.DragAndDrop.zindex */
386 zindex: 1000,
387
388 /** @id MochiKit.DragAndDrop.revert */
389 revert: false,
390
391 /** @id MochiKit.DragAndDrop.scroll */
392 scroll: false,
393
394 /** @id MochiKit.DragAndDrop.scrollSensitivity */
395 scrollSensitivity: 20,
396
397 /** @id MochiKit.DragAndDrop.scrollSpeed */
398 scrollSpeed: 15,
399 // false, or xy or [x, y] or function (x, y){return [x, y];}
400
401 /** @id MochiKit.DragAndDrop.snap */
402 snap: false
403 }, options);
404
405 var d = MochiKit.DOM;
406 this.element = d.getElement(element);
407
408 if (options.handle && (typeof(options.handle) == 'string')) {
409 this.handle = d.getFirstElementByTagAndClassName(null,
410 options.handle, this.element);
411 }
412 if (!this.handle) {
413 this.handle = d.getElement(options.handle);
414 }
415 if (!this.handle) {
416 this.handle = this.element;
417 }
418
419 if (options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
420 options.scroll = d.getElement(options.scroll);
421 this._isScrollChild = MochiKit.DOM.isChildNode(this.element, options.scroll);
422 }
423
424 MochiKit.Style.makePositioned(this.element); // fix IE
425
426 this.delta = this.currentDelta();
427 this.options = options;
428 this.dragging = false;
429
430 this.eventMouseDown = MochiKit.Signal.connect(this.handle,
431 'onmousedown', this, this.initDrag);
432 MochiKit.DragAndDrop.Draggables.register(this);
433 },
434
435 /** @id MochiKit.DragAndDrop.destroy */
436 destroy: function () {
437 MochiKit.Signal.disconnect(this.eventMouseDown);
438 MochiKit.DragAndDrop.Draggables.unregister(this);
439 },
440
441 /** @id MochiKit.DragAndDrop.currentDelta */
442 currentDelta: function () {
443 var s = MochiKit.Style.getStyle;
444 return [
445 parseInt(s(this.element, 'left') || '0'),
446 parseInt(s(this.element, 'top') || '0')];
447 },
448
449 /** @id MochiKit.DragAndDrop.initDrag */
450 initDrag: function (event) {
451 if (!event.mouse().button.left) {
452 return;
453 }
454 // abort on form elements, fixes a Firefox issue
455 var src = event.target();
456 var tagName = (src.tagName || '').toUpperCase();
457 if (tagName === 'INPUT' || tagName === 'SELECT' ||
458 tagName === 'OPTION' || tagName === 'BUTTON' ||
459 tagName === 'TEXTAREA') {
460 return;
461 }
462
463 if (this._revert) {
464 this._revert.cancel();
465 this._revert = null;
466 }
467
468 var pointer = event.mouse();
469 var pos = MochiKit.Position.cumulativeOffset(this.element);
470 this.offset = [pointer.page.x - pos.x, pointer.page.y - pos.y];
471
472 MochiKit.DragAndDrop.Draggables.activate(this);
473 event.stop();
474 },
475
476 /** @id MochiKit.DragAndDrop.startDrag */
477 startDrag: function (event) {
478 this.dragging = true;
479 if (this.options.selectclass) {
480 MochiKit.DOM.addElementClass(this.element,
481 this.options.selectclass);
482 }
483 if (this.options.zindex) {
484 this.originalZ = parseInt(MochiKit.Style.getStyle(this.element,
485 'z-index') || '0');
486 this.element.style.zIndex = this.options.zindex;
487 }
488
489 if (this.options.ghosting) {
490 this._clone = this.element.cloneNode(true);
491 this.ghostPosition = MochiKit.Position.absolutize(this.element);
492 this.element.parentNode.insertBefore(this._clone, this.element);
493 }
494
495 if (this.options.scroll) {
496 if (this.options.scroll == window) {
497 var where = this._getWindowScroll(this.options.scroll);
498 this.originalScrollLeft = where.left;
499 this.originalScrollTop = where.top;
500 } else {
501 this.originalScrollLeft = this.options.scroll.scrollLeft;
502 this.originalScrollTop = this.options.scroll.scrollTop;
503 }
504 }
505
506 MochiKit.DragAndDrop.Droppables.prepare(this.element);
507 MochiKit.DragAndDrop.Draggables.notify('start', this, event);
508 if (this.options.starteffect) {
509 this.options.starteffect(this.element);
510 }
511 },
512
513 /** @id MochiKit.DragAndDrop.updateDrag */
514 updateDrag: function (event, pointer) {
515 if (!this.dragging) {
516 this.startDrag(event);
517 }
518 MochiKit.Position.prepare();
519 MochiKit.DragAndDrop.Droppables.show(pointer, this.element);
520 MochiKit.DragAndDrop.Draggables.notify('drag', this, event);
521 this.draw(pointer);
522 this.options.onchange(this);
523
524 if (this.options.scroll) {
525 this.stopScrolling();
526 var p, q;
527 if (this.options.scroll == window) {
528 var s = this._getWindowScroll(this.options.scroll);
529 p = new MochiKit.Style.Coordinates(s.left, s.top);
530 q = new MochiKit.Style.Coordinates(s.left + s.width,
531 s.top + s.height);
532 } else {
533 p = MochiKit.Position.page(this.options.scroll);
534 p.x += this.options.scroll.scrollLeft;
535 p.y += this.options.scroll.scrollTop;
536 p.x += (window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0);
537 p.y += (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0);
538 q = new MochiKit.Style.Coordinates(p.x + this.options.scroll.offsetWidth,
539 p.y + this.options.scroll.offsetHeight);
540 }
541 var speed = [0, 0];
542 if (pointer.page.x > (q.x - this.options.scrollSensitivity)) {
543 speed[0] = pointer.page.x - (q.x - this.options.scrollSensitivity);
544 } else if (pointer.page.x < (p.x + this.options.scrollSensitivity)) {
545 speed[0] = pointer.page.x - (p.x + this.options.scrollSensitivity);
546 }
547 if (pointer.page.y > (q.y - this.options.scrollSensitivity)) {
548 speed[1] = pointer.page.y - (q.y - this.options.scrollSensitivity);
549 } else if (pointer.page.y < (p.y + this.options.scrollSensitivity)) {
550 speed[1] = pointer.page.y - (p.y + this.options.scrollSensitivity);
551 }
552 this.startScrolling(speed);
553 }
554
555 // fix AppleWebKit rendering
556 if (/AppleWebKit/.test(navigator.appVersion)) {
557 window.scrollBy(0, 0);
558 }
559 event.stop();
560 },
561
562 /** @id MochiKit.DragAndDrop.finishDrag */
563 finishDrag: function (event, success) {
564 var dr = MochiKit.DragAndDrop;
565 this.dragging = false;
566 if (this.options.selectclass) {
567 MochiKit.DOM.removeElementClass(this.element,
568 this.options.selectclass);
569 }
570
571 if (this.options.ghosting) {
572 // XXX: from a user point of view, it would be better to remove
573 // the node only *after* the MochiKit.Visual.Move end when used
574 // with revert.
575 MochiKit.Position.relativize(this.element, this.ghostPosition);
576 MochiKit.DOM.removeElement(this._clone);
577 this._clone = null;
578 }
579
580 if (success) {
581 dr.Droppables.fire(event, this.element);
582 }
583 dr.Draggables.notify('end', this, event);
584
585 var revert = this.options.revert;
586 if (revert && typeof(revert) == 'function') {
587 revert = revert(this.element);
588 }
589
590 var d = this.currentDelta();
591 if (revert && this.options.reverteffect) {
592 this._revert = this.options.reverteffect(this.element,
593 d[1] - this.delta[1], d[0] - this.delta[0]);
594 } else {
595 this.delta = d;
596 }
597
598 if (this.options.zindex) {
599 this.element.style.zIndex = this.originalZ;
600 }
601
602 if (this.options.endeffect) {
603 this.options.endeffect(this.element);
604 }
605
606 dr.Draggables.deactivate();
607 dr.Droppables.reset(this.element);
608 },
609
610 /** @id MochiKit.DragAndDrop.keyPress */
611 keyPress: function (event) {
612 if (event.key().string != "KEY_ESCAPE") {
613 return;
614 }
615 this.finishDrag(event, false);
616 event.stop();
617 },
618
619 /** @id MochiKit.DragAndDrop.endDrag */
620 endDrag: function (event) {
621 if (!this.dragging) {
622 return;
623 }
624 this.stopScrolling();
625 this.finishDrag(event, true);
626 event.stop();
627 },
628
629 /** @id MochiKit.DragAndDrop.draw */
630 draw: function (point) {
631 var pos = MochiKit.Position.cumulativeOffset(this.element);
632 var d = this.currentDelta();
633 pos.x -= d[0];
634 pos.y -= d[1];
635
636 if (this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
637 pos.x -= this.options.scroll.scrollLeft - this.originalScrollLeft;
638 pos.y -= this.options.scroll.scrollTop - this.originalScrollTop;
639 }
640
641 var p = [point.page.x - pos.x - this.offset[0],
642 point.page.y - pos.y - this.offset[1]];
643
644 if (this.options.snap) {
645 if (typeof(this.options.snap) == 'function') {
646 p = this.options.snap(p[0], p[1]);
647 } else {
648 if (this.options.snap instanceof Array) {
649 var i = -1;
650 p = MochiKit.Base.map(MochiKit.Base.bind(function (v) {
651 i += 1;
652 return Math.round(v/this.options.snap[i]) *
653 this.options.snap[i];
654 }, this), p);
655 } else {
656 p = MochiKit.Base.map(MochiKit.Base.bind(function (v) {
657 return Math.round(v/this.options.snap) *
658 this.options.snap;
659 }, this), p);
660 }
661 }
662 }
663 var style = this.element.style;
664 if ((!this.options.constraint) ||
665 (this.options.constraint == 'horizontal')) {
666 style.left = p[0] + 'px';
667 }
668 if ((!this.options.constraint) ||
669 (this.options.constraint == 'vertical')) {
670 style.top = p[1] + 'px';
671 }
672 if (style.visibility == 'hidden') {
673 style.visibility = ''; // fix gecko rendering
674 }
675 },
676
677 /** @id MochiKit.DragAndDrop.stopScrolling */
678 stopScrolling: function () {
679 if (this.scrollInterval) {
680 clearInterval(this.scrollInterval);
681 this.scrollInterval = null;
682 MochiKit.DragAndDrop.Draggables._lastScrollPointer = null;
683 }
684 },
685
686 /** @id MochiKit.DragAndDrop.startScrolling */
687 startScrolling: function (speed) {
688 if (!speed[0] && !speed[1]) {
689 return;
690 }
691 this.scrollSpeed = [speed[0] * this.options.scrollSpeed,
692 speed[1] * this.options.scrollSpeed];
693 this.lastScrolled = new Date();
694 this.scrollInterval = setInterval(MochiKit.Base.bind(this.scroll, this), 10);
695 },
696
697 /** @id MochiKit.DragAndDrop.scroll */
698 scroll: function () {
699 var current = new Date();
700 var delta = current - this.lastScrolled;
701 this.lastScrolled = current;
702
703 if (this.options.scroll == window) {
704 var s = this._getWindowScroll(this.options.scroll);
705 if (this.scrollSpeed[0] || this.scrollSpeed[1]) {
706 var dm = delta / 1000;
707 this.options.scroll.scrollTo(s.left + dm * this.scrollSpeed[0],
708 s.top + dm * this.scrollSpeed[1]);
709 }
710 } else {
711 this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
712 this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
713 }
714
715 var d = MochiKit.DragAndDrop;
716
717 MochiKit.Position.prepare();
718 d.Droppables.show(d.Draggables._lastPointer, this.element);
719 d.Draggables.notify('drag', this);
720 if (this._isScrollChild) {
721 d.Draggables._lastScrollPointer = d.Draggables._lastScrollPointer || d.Draggables._lastPointer;
722 d.Draggables._lastScrollPointer.x += this.scrollSpeed[0] * delta / 1000;
723 d.Draggables._lastScrollPointer.y += this.scrollSpeed[1] * delta / 1000;
724 if (d.Draggables._lastScrollPointer.x < 0) {
725 d.Draggables._lastScrollPointer.x = 0;
726 }
727 if (d.Draggables._lastScrollPointer.y < 0) {
728 d.Draggables._lastScrollPointer.y = 0;
729 }
730 this.draw(d.Draggables._lastScrollPointer);
731 }
732
733 this.options.onchange(this);
734 },
735
736 _getWindowScroll: function (win) {
737 var vp, w, h;
738 MochiKit.DOM.withWindow(win, function () {
739 vp = MochiKit.Style.getViewportPosition(win.document);
740 });
741 if (win.innerWidth) {
742 w = win.innerWidth;
743 h = win.innerHeight;
744 } else if (win.document.documentElement && win.document.documentElement.clientWidth) {
745 w = win.document.documentElement.clientWidth;
746 h = win.document.documentElement.clientHeight;
747 } else {
748 w = win.document.body.offsetWidth;
749 h = win.document.body.offsetHeight;
750 }
751 return {top: vp.y, left: vp.x, width: w, height: h};
752 },
753
754 /** @id MochiKit.DragAndDrop.repr */
755 repr: function () {
756 return '[' + this.__class__.NAME + ", options:" + MochiKit.Base.repr(this.options) + "]";
757 }
758};
759
760MochiKit.DragAndDrop.__new__ = function () {
761 MochiKit.Base.nameFunctions(this);
762};
763
764MochiKit.DragAndDrop.__new__();
765
766MochiKit.Base._exportSymbols(this, MochiKit.DragAndDrop);