1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/testing/mochitest/tests/MochiKit-1.4.2/MochiKit/DragAndDrop.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,793 @@ 1.4 +/*** 1.5 +MochiKit.DragAndDrop 1.4.2 1.6 + 1.7 +See <http://mochikit.com/> for documentation, downloads, license, etc. 1.8 + 1.9 +Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) 1.10 + Mochi-ized By Thomas Herve (_firstname_@nimail.org) 1.11 + 1.12 +***/ 1.13 + 1.14 +MochiKit.Base._deps('DragAndDrop', ['Base', 'Iter', 'DOM', 'Signal', 'Visual', 'Position']); 1.15 + 1.16 +MochiKit.DragAndDrop.NAME = 'MochiKit.DragAndDrop'; 1.17 +MochiKit.DragAndDrop.VERSION = '1.4.2'; 1.18 + 1.19 +MochiKit.DragAndDrop.__repr__ = function () { 1.20 + return '[' + this.NAME + ' ' + this.VERSION + ']'; 1.21 +}; 1.22 + 1.23 +MochiKit.DragAndDrop.toString = function () { 1.24 + return this.__repr__(); 1.25 +}; 1.26 + 1.27 +MochiKit.DragAndDrop.EXPORT = [ 1.28 + "Droppable", 1.29 + "Draggable" 1.30 +]; 1.31 + 1.32 +MochiKit.DragAndDrop.EXPORT_OK = [ 1.33 + "Droppables", 1.34 + "Draggables" 1.35 +]; 1.36 + 1.37 +MochiKit.DragAndDrop.Droppables = { 1.38 + /*** 1.39 + 1.40 + Manage all droppables. Shouldn't be used, use the Droppable object instead. 1.41 + 1.42 + ***/ 1.43 + drops: [], 1.44 + 1.45 + remove: function (element) { 1.46 + this.drops = MochiKit.Base.filter(function (d) { 1.47 + return d.element != MochiKit.DOM.getElement(element); 1.48 + }, this.drops); 1.49 + }, 1.50 + 1.51 + register: function (drop) { 1.52 + this.drops.push(drop); 1.53 + }, 1.54 + 1.55 + unregister: function (drop) { 1.56 + this.drops = MochiKit.Base.filter(function (d) { 1.57 + return d != drop; 1.58 + }, this.drops); 1.59 + }, 1.60 + 1.61 + prepare: function (element) { 1.62 + MochiKit.Base.map(function (drop) { 1.63 + if (drop.isAccepted(element)) { 1.64 + if (drop.options.activeclass) { 1.65 + MochiKit.DOM.addElementClass(drop.element, 1.66 + drop.options.activeclass); 1.67 + } 1.68 + drop.options.onactive(drop.element, element); 1.69 + } 1.70 + }, this.drops); 1.71 + }, 1.72 + 1.73 + findDeepestChild: function (drops) { 1.74 + deepest = drops[0]; 1.75 + 1.76 + for (i = 1; i < drops.length; ++i) { 1.77 + if (MochiKit.DOM.isChildNode(drops[i].element, deepest.element)) { 1.78 + deepest = drops[i]; 1.79 + } 1.80 + } 1.81 + return deepest; 1.82 + }, 1.83 + 1.84 + show: function (point, element) { 1.85 + if (!this.drops.length) { 1.86 + return; 1.87 + } 1.88 + var affected = []; 1.89 + 1.90 + if (this.last_active) { 1.91 + this.last_active.deactivate(); 1.92 + } 1.93 + MochiKit.Iter.forEach(this.drops, function (drop) { 1.94 + if (drop.isAffected(point, element)) { 1.95 + affected.push(drop); 1.96 + } 1.97 + }); 1.98 + if (affected.length > 0) { 1.99 + drop = this.findDeepestChild(affected); 1.100 + MochiKit.Position.within(drop.element, point.page.x, point.page.y); 1.101 + drop.options.onhover(element, drop.element, 1.102 + MochiKit.Position.overlap(drop.options.overlap, drop.element)); 1.103 + drop.activate(); 1.104 + } 1.105 + }, 1.106 + 1.107 + fire: function (event, element) { 1.108 + if (!this.last_active) { 1.109 + return; 1.110 + } 1.111 + MochiKit.Position.prepare(); 1.112 + 1.113 + if (this.last_active.isAffected(event.mouse(), element)) { 1.114 + this.last_active.options.ondrop(element, 1.115 + this.last_active.element, event); 1.116 + } 1.117 + }, 1.118 + 1.119 + reset: function (element) { 1.120 + MochiKit.Base.map(function (drop) { 1.121 + if (drop.options.activeclass) { 1.122 + MochiKit.DOM.removeElementClass(drop.element, 1.123 + drop.options.activeclass); 1.124 + } 1.125 + drop.options.ondesactive(drop.element, element); 1.126 + }, this.drops); 1.127 + if (this.last_active) { 1.128 + this.last_active.deactivate(); 1.129 + } 1.130 + } 1.131 +}; 1.132 + 1.133 +/** @id MochiKit.DragAndDrop.Droppable */ 1.134 +MochiKit.DragAndDrop.Droppable = function (element, options) { 1.135 + var cls = arguments.callee; 1.136 + if (!(this instanceof cls)) { 1.137 + return new cls(element, options); 1.138 + } 1.139 + this.__init__(element, options); 1.140 +}; 1.141 + 1.142 +MochiKit.DragAndDrop.Droppable.prototype = { 1.143 + /*** 1.144 + 1.145 + A droppable object. Simple use is to create giving an element: 1.146 + 1.147 + new MochiKit.DragAndDrop.Droppable('myelement'); 1.148 + 1.149 + Generally you'll want to define the 'ondrop' function and maybe the 1.150 + 'accept' option to filter draggables. 1.151 + 1.152 + ***/ 1.153 + __class__: MochiKit.DragAndDrop.Droppable, 1.154 + 1.155 + __init__: function (element, /* optional */options) { 1.156 + var d = MochiKit.DOM; 1.157 + var b = MochiKit.Base; 1.158 + this.element = d.getElement(element); 1.159 + this.options = b.update({ 1.160 + 1.161 + /** @id MochiKit.DragAndDrop.greedy */ 1.162 + greedy: true, 1.163 + 1.164 + /** @id MochiKit.DragAndDrop.hoverclass */ 1.165 + hoverclass: null, 1.166 + 1.167 + /** @id MochiKit.DragAndDrop.activeclass */ 1.168 + activeclass: null, 1.169 + 1.170 + /** @id MochiKit.DragAndDrop.hoverfunc */ 1.171 + hoverfunc: b.noop, 1.172 + 1.173 + /** @id MochiKit.DragAndDrop.accept */ 1.174 + accept: null, 1.175 + 1.176 + /** @id MochiKit.DragAndDrop.onactive */ 1.177 + onactive: b.noop, 1.178 + 1.179 + /** @id MochiKit.DragAndDrop.ondesactive */ 1.180 + ondesactive: b.noop, 1.181 + 1.182 + /** @id MochiKit.DragAndDrop.onhover */ 1.183 + onhover: b.noop, 1.184 + 1.185 + /** @id MochiKit.DragAndDrop.ondrop */ 1.186 + ondrop: b.noop, 1.187 + 1.188 + /** @id MochiKit.DragAndDrop.containment */ 1.189 + containment: [], 1.190 + tree: false 1.191 + }, options); 1.192 + 1.193 + // cache containers 1.194 + this.options._containers = []; 1.195 + b.map(MochiKit.Base.bind(function (c) { 1.196 + this.options._containers.push(d.getElement(c)); 1.197 + }, this), this.options.containment); 1.198 + 1.199 + MochiKit.Style.makePositioned(this.element); // fix IE 1.200 + 1.201 + MochiKit.DragAndDrop.Droppables.register(this); 1.202 + }, 1.203 + 1.204 + /** @id MochiKit.DragAndDrop.isContained */ 1.205 + isContained: function (element) { 1.206 + if (this.options._containers.length) { 1.207 + var containmentNode; 1.208 + if (this.options.tree) { 1.209 + containmentNode = element.treeNode; 1.210 + } else { 1.211 + containmentNode = element.parentNode; 1.212 + } 1.213 + return MochiKit.Iter.some(this.options._containers, function (c) { 1.214 + return containmentNode == c; 1.215 + }); 1.216 + } else { 1.217 + return true; 1.218 + } 1.219 + }, 1.220 + 1.221 + /** @id MochiKit.DragAndDrop.isAccepted */ 1.222 + isAccepted: function (element) { 1.223 + return ((!this.options.accept) || MochiKit.Iter.some( 1.224 + this.options.accept, function (c) { 1.225 + return MochiKit.DOM.hasElementClass(element, c); 1.226 + })); 1.227 + }, 1.228 + 1.229 + /** @id MochiKit.DragAndDrop.isAffected */ 1.230 + isAffected: function (point, element) { 1.231 + return ((this.element != element) && 1.232 + this.isContained(element) && 1.233 + this.isAccepted(element) && 1.234 + MochiKit.Position.within(this.element, point.page.x, 1.235 + point.page.y)); 1.236 + }, 1.237 + 1.238 + /** @id MochiKit.DragAndDrop.deactivate */ 1.239 + deactivate: function () { 1.240 + /*** 1.241 + 1.242 + A droppable is deactivate when a draggable has been over it and left. 1.243 + 1.244 + ***/ 1.245 + if (this.options.hoverclass) { 1.246 + MochiKit.DOM.removeElementClass(this.element, 1.247 + this.options.hoverclass); 1.248 + } 1.249 + this.options.hoverfunc(this.element, false); 1.250 + MochiKit.DragAndDrop.Droppables.last_active = null; 1.251 + }, 1.252 + 1.253 + /** @id MochiKit.DragAndDrop.activate */ 1.254 + activate: function () { 1.255 + /*** 1.256 + 1.257 + A droppable is active when a draggable is over it. 1.258 + 1.259 + ***/ 1.260 + if (this.options.hoverclass) { 1.261 + MochiKit.DOM.addElementClass(this.element, this.options.hoverclass); 1.262 + } 1.263 + this.options.hoverfunc(this.element, true); 1.264 + MochiKit.DragAndDrop.Droppables.last_active = this; 1.265 + }, 1.266 + 1.267 + /** @id MochiKit.DragAndDrop.destroy */ 1.268 + destroy: function () { 1.269 + /*** 1.270 + 1.271 + Delete this droppable. 1.272 + 1.273 + ***/ 1.274 + MochiKit.DragAndDrop.Droppables.unregister(this); 1.275 + }, 1.276 + 1.277 + /** @id MochiKit.DragAndDrop.repr */ 1.278 + repr: function () { 1.279 + return '[' + this.__class__.NAME + ", options:" + MochiKit.Base.repr(this.options) + "]"; 1.280 + } 1.281 +}; 1.282 + 1.283 +MochiKit.DragAndDrop.Draggables = { 1.284 + /*** 1.285 + 1.286 + Manage draggables elements. Not intended to direct use. 1.287 + 1.288 + ***/ 1.289 + drags: [], 1.290 + 1.291 + register: function (draggable) { 1.292 + if (this.drags.length === 0) { 1.293 + var conn = MochiKit.Signal.connect; 1.294 + this.eventMouseUp = conn(document, 'onmouseup', this, this.endDrag); 1.295 + this.eventMouseMove = conn(document, 'onmousemove', this, 1.296 + this.updateDrag); 1.297 + this.eventKeypress = conn(document, 'onkeypress', this, 1.298 + this.keyPress); 1.299 + } 1.300 + this.drags.push(draggable); 1.301 + }, 1.302 + 1.303 + unregister: function (draggable) { 1.304 + this.drags = MochiKit.Base.filter(function (d) { 1.305 + return d != draggable; 1.306 + }, this.drags); 1.307 + if (this.drags.length === 0) { 1.308 + var disc = MochiKit.Signal.disconnect; 1.309 + disc(this.eventMouseUp); 1.310 + disc(this.eventMouseMove); 1.311 + disc(this.eventKeypress); 1.312 + } 1.313 + }, 1.314 + 1.315 + activate: function (draggable) { 1.316 + // allows keypress events if window is not currently focused 1.317 + // fails for Safari 1.318 + window.focus(); 1.319 + this.activeDraggable = draggable; 1.320 + }, 1.321 + 1.322 + deactivate: function () { 1.323 + this.activeDraggable = null; 1.324 + }, 1.325 + 1.326 + updateDrag: function (event) { 1.327 + if (!this.activeDraggable) { 1.328 + return; 1.329 + } 1.330 + var pointer = event.mouse(); 1.331 + // Mozilla-based browsers fire successive mousemove events with 1.332 + // the same coordinates, prevent needless redrawing (moz bug?) 1.333 + if (this._lastPointer && (MochiKit.Base.repr(this._lastPointer.page) == 1.334 + MochiKit.Base.repr(pointer.page))) { 1.335 + return; 1.336 + } 1.337 + this._lastPointer = pointer; 1.338 + this.activeDraggable.updateDrag(event, pointer); 1.339 + }, 1.340 + 1.341 + endDrag: function (event) { 1.342 + if (!this.activeDraggable) { 1.343 + return; 1.344 + } 1.345 + this._lastPointer = null; 1.346 + this.activeDraggable.endDrag(event); 1.347 + this.activeDraggable = null; 1.348 + }, 1.349 + 1.350 + keyPress: function (event) { 1.351 + if (this.activeDraggable) { 1.352 + this.activeDraggable.keyPress(event); 1.353 + } 1.354 + }, 1.355 + 1.356 + notify: function (eventName, draggable, event) { 1.357 + MochiKit.Signal.signal(this, eventName, draggable, event); 1.358 + } 1.359 +}; 1.360 + 1.361 +/** @id MochiKit.DragAndDrop.Draggable */ 1.362 +MochiKit.DragAndDrop.Draggable = function (element, options) { 1.363 + var cls = arguments.callee; 1.364 + if (!(this instanceof cls)) { 1.365 + return new cls(element, options); 1.366 + } 1.367 + this.__init__(element, options); 1.368 +}; 1.369 + 1.370 +MochiKit.DragAndDrop.Draggable.prototype = { 1.371 + /*** 1.372 + 1.373 + A draggable object. Simple instantiate : 1.374 + 1.375 + new MochiKit.DragAndDrop.Draggable('myelement'); 1.376 + 1.377 + ***/ 1.378 + __class__ : MochiKit.DragAndDrop.Draggable, 1.379 + 1.380 + __init__: function (element, /* optional */options) { 1.381 + var v = MochiKit.Visual; 1.382 + var b = MochiKit.Base; 1.383 + options = b.update({ 1.384 + 1.385 + /** @id MochiKit.DragAndDrop.handle */ 1.386 + handle: false, 1.387 + 1.388 + /** @id MochiKit.DragAndDrop.starteffect */ 1.389 + starteffect: function (innerelement) { 1.390 + this._savedOpacity = MochiKit.Style.getStyle(innerelement, 'opacity') || 1.0; 1.391 + new v.Opacity(innerelement, {duration:0.2, from:this._savedOpacity, to:0.7}); 1.392 + }, 1.393 + /** @id MochiKit.DragAndDrop.reverteffect */ 1.394 + reverteffect: function (innerelement, top_offset, left_offset) { 1.395 + var dur = Math.sqrt(Math.abs(top_offset^2) + 1.396 + Math.abs(left_offset^2))*0.02; 1.397 + return new v.Move(innerelement, 1.398 + {x: -left_offset, y: -top_offset, duration: dur}); 1.399 + }, 1.400 + 1.401 + /** @id MochiKit.DragAndDrop.endeffect */ 1.402 + endeffect: function (innerelement) { 1.403 + new v.Opacity(innerelement, {duration:0.2, from:0.7, to:this._savedOpacity}); 1.404 + }, 1.405 + 1.406 + /** @id MochiKit.DragAndDrop.onchange */ 1.407 + onchange: b.noop, 1.408 + 1.409 + /** @id MochiKit.DragAndDrop.zindex */ 1.410 + zindex: 1000, 1.411 + 1.412 + /** @id MochiKit.DragAndDrop.revert */ 1.413 + revert: false, 1.414 + 1.415 + /** @id MochiKit.DragAndDrop.scroll */ 1.416 + scroll: false, 1.417 + 1.418 + /** @id MochiKit.DragAndDrop.scrollSensitivity */ 1.419 + scrollSensitivity: 20, 1.420 + 1.421 + /** @id MochiKit.DragAndDrop.scrollSpeed */ 1.422 + scrollSpeed: 15, 1.423 + // false, or xy or [x, y] or function (x, y){return [x, y];} 1.424 + 1.425 + /** @id MochiKit.DragAndDrop.snap */ 1.426 + snap: false 1.427 + }, options); 1.428 + 1.429 + var d = MochiKit.DOM; 1.430 + this.element = d.getElement(element); 1.431 + 1.432 + if (options.handle && (typeof(options.handle) == 'string')) { 1.433 + this.handle = d.getFirstElementByTagAndClassName(null, 1.434 + options.handle, this.element); 1.435 + } 1.436 + if (!this.handle) { 1.437 + this.handle = d.getElement(options.handle); 1.438 + } 1.439 + if (!this.handle) { 1.440 + this.handle = this.element; 1.441 + } 1.442 + 1.443 + if (options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) { 1.444 + options.scroll = d.getElement(options.scroll); 1.445 + this._isScrollChild = MochiKit.DOM.isChildNode(this.element, options.scroll); 1.446 + } 1.447 + 1.448 + MochiKit.Style.makePositioned(this.element); // fix IE 1.449 + 1.450 + this.delta = this.currentDelta(); 1.451 + this.options = options; 1.452 + this.dragging = false; 1.453 + 1.454 + this.eventMouseDown = MochiKit.Signal.connect(this.handle, 1.455 + 'onmousedown', this, this.initDrag); 1.456 + MochiKit.DragAndDrop.Draggables.register(this); 1.457 + }, 1.458 + 1.459 + /** @id MochiKit.DragAndDrop.destroy */ 1.460 + destroy: function () { 1.461 + MochiKit.Signal.disconnect(this.eventMouseDown); 1.462 + MochiKit.DragAndDrop.Draggables.unregister(this); 1.463 + }, 1.464 + 1.465 + /** @id MochiKit.DragAndDrop.currentDelta */ 1.466 + currentDelta: function () { 1.467 + var s = MochiKit.Style.getStyle; 1.468 + return [ 1.469 + parseInt(s(this.element, 'left') || '0'), 1.470 + parseInt(s(this.element, 'top') || '0')]; 1.471 + }, 1.472 + 1.473 + /** @id MochiKit.DragAndDrop.initDrag */ 1.474 + initDrag: function (event) { 1.475 + if (!event.mouse().button.left) { 1.476 + return; 1.477 + } 1.478 + // abort on form elements, fixes a Firefox issue 1.479 + var src = event.target(); 1.480 + var tagName = (src.tagName || '').toUpperCase(); 1.481 + if (tagName === 'INPUT' || tagName === 'SELECT' || 1.482 + tagName === 'OPTION' || tagName === 'BUTTON' || 1.483 + tagName === 'TEXTAREA') { 1.484 + return; 1.485 + } 1.486 + 1.487 + if (this._revert) { 1.488 + this._revert.cancel(); 1.489 + this._revert = null; 1.490 + } 1.491 + 1.492 + var pointer = event.mouse(); 1.493 + var pos = MochiKit.Position.cumulativeOffset(this.element); 1.494 + this.offset = [pointer.page.x - pos.x, pointer.page.y - pos.y]; 1.495 + 1.496 + MochiKit.DragAndDrop.Draggables.activate(this); 1.497 + event.stop(); 1.498 + }, 1.499 + 1.500 + /** @id MochiKit.DragAndDrop.startDrag */ 1.501 + startDrag: function (event) { 1.502 + this.dragging = true; 1.503 + if (this.options.selectclass) { 1.504 + MochiKit.DOM.addElementClass(this.element, 1.505 + this.options.selectclass); 1.506 + } 1.507 + if (this.options.zindex) { 1.508 + this.originalZ = parseInt(MochiKit.Style.getStyle(this.element, 1.509 + 'z-index') || '0'); 1.510 + this.element.style.zIndex = this.options.zindex; 1.511 + } 1.512 + 1.513 + if (this.options.ghosting) { 1.514 + this._clone = this.element.cloneNode(true); 1.515 + this.ghostPosition = MochiKit.Position.absolutize(this.element); 1.516 + this.element.parentNode.insertBefore(this._clone, this.element); 1.517 + } 1.518 + 1.519 + if (this.options.scroll) { 1.520 + if (this.options.scroll == window) { 1.521 + var where = this._getWindowScroll(this.options.scroll); 1.522 + this.originalScrollLeft = where.left; 1.523 + this.originalScrollTop = where.top; 1.524 + } else { 1.525 + this.originalScrollLeft = this.options.scroll.scrollLeft; 1.526 + this.originalScrollTop = this.options.scroll.scrollTop; 1.527 + } 1.528 + } 1.529 + 1.530 + MochiKit.DragAndDrop.Droppables.prepare(this.element); 1.531 + MochiKit.DragAndDrop.Draggables.notify('start', this, event); 1.532 + if (this.options.starteffect) { 1.533 + this.options.starteffect(this.element); 1.534 + } 1.535 + }, 1.536 + 1.537 + /** @id MochiKit.DragAndDrop.updateDrag */ 1.538 + updateDrag: function (event, pointer) { 1.539 + if (!this.dragging) { 1.540 + this.startDrag(event); 1.541 + } 1.542 + MochiKit.Position.prepare(); 1.543 + MochiKit.DragAndDrop.Droppables.show(pointer, this.element); 1.544 + MochiKit.DragAndDrop.Draggables.notify('drag', this, event); 1.545 + this.draw(pointer); 1.546 + this.options.onchange(this); 1.547 + 1.548 + if (this.options.scroll) { 1.549 + this.stopScrolling(); 1.550 + var p, q; 1.551 + if (this.options.scroll == window) { 1.552 + var s = this._getWindowScroll(this.options.scroll); 1.553 + p = new MochiKit.Style.Coordinates(s.left, s.top); 1.554 + q = new MochiKit.Style.Coordinates(s.left + s.width, 1.555 + s.top + s.height); 1.556 + } else { 1.557 + p = MochiKit.Position.page(this.options.scroll); 1.558 + p.x += this.options.scroll.scrollLeft; 1.559 + p.y += this.options.scroll.scrollTop; 1.560 + p.x += (window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0); 1.561 + p.y += (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0); 1.562 + q = new MochiKit.Style.Coordinates(p.x + this.options.scroll.offsetWidth, 1.563 + p.y + this.options.scroll.offsetHeight); 1.564 + } 1.565 + var speed = [0, 0]; 1.566 + if (pointer.page.x > (q.x - this.options.scrollSensitivity)) { 1.567 + speed[0] = pointer.page.x - (q.x - this.options.scrollSensitivity); 1.568 + } else if (pointer.page.x < (p.x + this.options.scrollSensitivity)) { 1.569 + speed[0] = pointer.page.x - (p.x + this.options.scrollSensitivity); 1.570 + } 1.571 + if (pointer.page.y > (q.y - this.options.scrollSensitivity)) { 1.572 + speed[1] = pointer.page.y - (q.y - this.options.scrollSensitivity); 1.573 + } else if (pointer.page.y < (p.y + this.options.scrollSensitivity)) { 1.574 + speed[1] = pointer.page.y - (p.y + this.options.scrollSensitivity); 1.575 + } 1.576 + this.startScrolling(speed); 1.577 + } 1.578 + 1.579 + // fix AppleWebKit rendering 1.580 + if (/AppleWebKit/.test(navigator.appVersion)) { 1.581 + window.scrollBy(0, 0); 1.582 + } 1.583 + event.stop(); 1.584 + }, 1.585 + 1.586 + /** @id MochiKit.DragAndDrop.finishDrag */ 1.587 + finishDrag: function (event, success) { 1.588 + var dr = MochiKit.DragAndDrop; 1.589 + this.dragging = false; 1.590 + if (this.options.selectclass) { 1.591 + MochiKit.DOM.removeElementClass(this.element, 1.592 + this.options.selectclass); 1.593 + } 1.594 + 1.595 + if (this.options.ghosting) { 1.596 + // XXX: from a user point of view, it would be better to remove 1.597 + // the node only *after* the MochiKit.Visual.Move end when used 1.598 + // with revert. 1.599 + MochiKit.Position.relativize(this.element, this.ghostPosition); 1.600 + MochiKit.DOM.removeElement(this._clone); 1.601 + this._clone = null; 1.602 + } 1.603 + 1.604 + if (success) { 1.605 + dr.Droppables.fire(event, this.element); 1.606 + } 1.607 + dr.Draggables.notify('end', this, event); 1.608 + 1.609 + var revert = this.options.revert; 1.610 + if (revert && typeof(revert) == 'function') { 1.611 + revert = revert(this.element); 1.612 + } 1.613 + 1.614 + var d = this.currentDelta(); 1.615 + if (revert && this.options.reverteffect) { 1.616 + this._revert = this.options.reverteffect(this.element, 1.617 + d[1] - this.delta[1], d[0] - this.delta[0]); 1.618 + } else { 1.619 + this.delta = d; 1.620 + } 1.621 + 1.622 + if (this.options.zindex) { 1.623 + this.element.style.zIndex = this.originalZ; 1.624 + } 1.625 + 1.626 + if (this.options.endeffect) { 1.627 + this.options.endeffect(this.element); 1.628 + } 1.629 + 1.630 + dr.Draggables.deactivate(); 1.631 + dr.Droppables.reset(this.element); 1.632 + }, 1.633 + 1.634 + /** @id MochiKit.DragAndDrop.keyPress */ 1.635 + keyPress: function (event) { 1.636 + if (event.key().string != "KEY_ESCAPE") { 1.637 + return; 1.638 + } 1.639 + this.finishDrag(event, false); 1.640 + event.stop(); 1.641 + }, 1.642 + 1.643 + /** @id MochiKit.DragAndDrop.endDrag */ 1.644 + endDrag: function (event) { 1.645 + if (!this.dragging) { 1.646 + return; 1.647 + } 1.648 + this.stopScrolling(); 1.649 + this.finishDrag(event, true); 1.650 + event.stop(); 1.651 + }, 1.652 + 1.653 + /** @id MochiKit.DragAndDrop.draw */ 1.654 + draw: function (point) { 1.655 + var pos = MochiKit.Position.cumulativeOffset(this.element); 1.656 + var d = this.currentDelta(); 1.657 + pos.x -= d[0]; 1.658 + pos.y -= d[1]; 1.659 + 1.660 + if (this.options.scroll && (this.options.scroll != window && this._isScrollChild)) { 1.661 + pos.x -= this.options.scroll.scrollLeft - this.originalScrollLeft; 1.662 + pos.y -= this.options.scroll.scrollTop - this.originalScrollTop; 1.663 + } 1.664 + 1.665 + var p = [point.page.x - pos.x - this.offset[0], 1.666 + point.page.y - pos.y - this.offset[1]]; 1.667 + 1.668 + if (this.options.snap) { 1.669 + if (typeof(this.options.snap) == 'function') { 1.670 + p = this.options.snap(p[0], p[1]); 1.671 + } else { 1.672 + if (this.options.snap instanceof Array) { 1.673 + var i = -1; 1.674 + p = MochiKit.Base.map(MochiKit.Base.bind(function (v) { 1.675 + i += 1; 1.676 + return Math.round(v/this.options.snap[i]) * 1.677 + this.options.snap[i]; 1.678 + }, this), p); 1.679 + } else { 1.680 + p = MochiKit.Base.map(MochiKit.Base.bind(function (v) { 1.681 + return Math.round(v/this.options.snap) * 1.682 + this.options.snap; 1.683 + }, this), p); 1.684 + } 1.685 + } 1.686 + } 1.687 + var style = this.element.style; 1.688 + if ((!this.options.constraint) || 1.689 + (this.options.constraint == 'horizontal')) { 1.690 + style.left = p[0] + 'px'; 1.691 + } 1.692 + if ((!this.options.constraint) || 1.693 + (this.options.constraint == 'vertical')) { 1.694 + style.top = p[1] + 'px'; 1.695 + } 1.696 + if (style.visibility == 'hidden') { 1.697 + style.visibility = ''; // fix gecko rendering 1.698 + } 1.699 + }, 1.700 + 1.701 + /** @id MochiKit.DragAndDrop.stopScrolling */ 1.702 + stopScrolling: function () { 1.703 + if (this.scrollInterval) { 1.704 + clearInterval(this.scrollInterval); 1.705 + this.scrollInterval = null; 1.706 + MochiKit.DragAndDrop.Draggables._lastScrollPointer = null; 1.707 + } 1.708 + }, 1.709 + 1.710 + /** @id MochiKit.DragAndDrop.startScrolling */ 1.711 + startScrolling: function (speed) { 1.712 + if (!speed[0] && !speed[1]) { 1.713 + return; 1.714 + } 1.715 + this.scrollSpeed = [speed[0] * this.options.scrollSpeed, 1.716 + speed[1] * this.options.scrollSpeed]; 1.717 + this.lastScrolled = new Date(); 1.718 + this.scrollInterval = setInterval(MochiKit.Base.bind(this.scroll, this), 10); 1.719 + }, 1.720 + 1.721 + /** @id MochiKit.DragAndDrop.scroll */ 1.722 + scroll: function () { 1.723 + var current = new Date(); 1.724 + var delta = current - this.lastScrolled; 1.725 + this.lastScrolled = current; 1.726 + 1.727 + if (this.options.scroll == window) { 1.728 + var s = this._getWindowScroll(this.options.scroll); 1.729 + if (this.scrollSpeed[0] || this.scrollSpeed[1]) { 1.730 + var dm = delta / 1000; 1.731 + this.options.scroll.scrollTo(s.left + dm * this.scrollSpeed[0], 1.732 + s.top + dm * this.scrollSpeed[1]); 1.733 + } 1.734 + } else { 1.735 + this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000; 1.736 + this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000; 1.737 + } 1.738 + 1.739 + var d = MochiKit.DragAndDrop; 1.740 + 1.741 + MochiKit.Position.prepare(); 1.742 + d.Droppables.show(d.Draggables._lastPointer, this.element); 1.743 + d.Draggables.notify('drag', this); 1.744 + if (this._isScrollChild) { 1.745 + d.Draggables._lastScrollPointer = d.Draggables._lastScrollPointer || d.Draggables._lastPointer; 1.746 + d.Draggables._lastScrollPointer.x += this.scrollSpeed[0] * delta / 1000; 1.747 + d.Draggables._lastScrollPointer.y += this.scrollSpeed[1] * delta / 1000; 1.748 + if (d.Draggables._lastScrollPointer.x < 0) { 1.749 + d.Draggables._lastScrollPointer.x = 0; 1.750 + } 1.751 + if (d.Draggables._lastScrollPointer.y < 0) { 1.752 + d.Draggables._lastScrollPointer.y = 0; 1.753 + } 1.754 + this.draw(d.Draggables._lastScrollPointer); 1.755 + } 1.756 + 1.757 + this.options.onchange(this); 1.758 + }, 1.759 + 1.760 + _getWindowScroll: function (win) { 1.761 + var vp, w, h; 1.762 + MochiKit.DOM.withWindow(win, function () { 1.763 + vp = MochiKit.Style.getViewportPosition(win.document); 1.764 + }); 1.765 + if (win.innerWidth) { 1.766 + w = win.innerWidth; 1.767 + h = win.innerHeight; 1.768 + } else if (win.document.documentElement && win.document.documentElement.clientWidth) { 1.769 + w = win.document.documentElement.clientWidth; 1.770 + h = win.document.documentElement.clientHeight; 1.771 + } else { 1.772 + w = win.document.body.offsetWidth; 1.773 + h = win.document.body.offsetHeight; 1.774 + } 1.775 + return {top: vp.y, left: vp.x, width: w, height: h}; 1.776 + }, 1.777 + 1.778 + /** @id MochiKit.DragAndDrop.repr */ 1.779 + repr: function () { 1.780 + return '[' + this.__class__.NAME + ", options:" + MochiKit.Base.repr(this.options) + "]"; 1.781 + } 1.782 +}; 1.783 + 1.784 +MochiKit.DragAndDrop.__new__ = function () { 1.785 + MochiKit.Base.nameFunctions(this); 1.786 + 1.787 + this.EXPORT_TAGS = { 1.788 + ":common": this.EXPORT, 1.789 + ":all": MochiKit.Base.concat(this.EXPORT, this.EXPORT_OK) 1.790 + }; 1.791 +}; 1.792 + 1.793 +MochiKit.DragAndDrop.__new__(); 1.794 + 1.795 +MochiKit.Base._exportSymbols(this, MochiKit.DragAndDrop); 1.796 +