sogo/UI/WebServerResources/SOGoDragAndDrop.js
Francis Lachapelle bec2e4b044 Monotone-Parent: f6b19068a08dfed75e7ea40b073cf352c44bf149
Monotone-Revision: b84126f7bcb792c12d98bfbf76e293a18f1c92cb

Monotone-Author: flachapelle@inverse.ca
Monotone-Date: 2007-05-25T14:31:24
Monotone-Branch: ca.inverse.sogo
2007-05-25 14:31:24 +00:00

254 lines
8.9 KiB
JavaScript

/* drag and drop */
/* HTMLElement interface */
var SOGODragAndDropSourceInterface = {
_removeGestureHandlers: function () {
window.removeEventListener("mousemove", this.dragGestureMouseMoveHandler, false);
window.removeEventListener("mouseup", this.dragGestureMouseUpHandler, false);
document._dragGestureStartPoint = null;
document._currentMouseGestureObject = null;
},
bind: function() {
this.addEventListener("mousedown", this.dragGestureMouseDownHandler, false);
},
dragGestureMouseDownHandler: function (event) {
if (event.button == 0) {
document._dragGestureStartPoint = new Array(event.clientX,
event.clientY);
document._currentMouseGestureObject = this;
window.addEventListener("mousemove", this.dragGestureMouseMoveHandler,
false);
window.addEventListener("mouseup", this.dragGestureMouseUpHandler,
false);
}
},
dragGestureMouseUpHandler: function (event) {
document._currentMouseGestureObject._removeGestureHandlers();
},
dragGestureMouseMoveHandler: function (event) {
var deltaX = event.clientX - document._dragGestureStartPoint[0];
var deltaY = event.clientY - document._dragGestureStartPoint[1];
if (Math.sqrt((deltaX * deltaX) + (deltaY * deltaY)) > 10) {
event.returnValue = true;
event.cancelBubble = true;
var object = document._currentMouseGestureObject;
var point = document._dragGestureStartPoint;
document.DNDManager.startDragging(object, point);
document._currentMouseGestureObject._removeGestureHandlers();
}
}
}
/* DNDManager */
document.DNDManager = {
lastSource: 0,
lastDestination: 0,
sources: new Array(),
destinations: new Array(),
registerSource: function (source) {
var id = source.getAttribute("id");
if (!id) {
id = "_dndSource" + (this.lastSource + 1);
source.setAttribute("id", id);
}
this.sources[id] = source;
this.lastSource++;
source.addInterface(SOGODragAndDropSourceInterface);
},
registerDestination: function (destination) {
var id = destination.getAttribute("id");
if (!id) {
id = "_dndDestination" + (this.lastDestination + 1);
destination.setAttribute("id", id);
}
this.destinations[id] = destination;
this.lastDestination++;
},
_lookupSource: function (target) {
var source = null;
var id = target.getAttribute("id");
if (id)
source = document.DNDManager.sources[id];
return source;
},
_lookupDestination: function (target) {
var destination = null;
var id = target.getAttribute("id");
if (id)
destination = document.DNDManager.destinations[id];
return destination;
},
startDragging: function (object, point) {
var source = document.DNDManager._lookupSource (object);
if (source) {
document.DNDManager.currentDndOperation = new document.DNDOperation(source, point);
window.addEventListener("mouseup",
document.DNDManager.destinationDrop, false);
window.addEventListener("mouseover",
document.DNDManager.destinationEnter, false);
window.addEventListener("mousemove",
document.DNDManager.destinationOver, false);
window.addEventListener("mouseout",
document.DNDManager.destinationExit, false);
}
},
destinationEnter: function (event) {
var operation = document.DNDManager.currentDndOperation;
var destination = document.DNDManager._lookupDestination (event.target);
if (operation && destination && destination.dndAcceptType) {
operation.type = null;
var i = 0;
while (operation.type == null
&& i < operation.types.length) {
if (destination.dndAcceptType(operation.types[i])) {
operation.type = operation.types[i];
operation.setDestination(destination);
if (destination.dndEnter)
destination.dndEnter(event, operation.source, operation.type);
}
else
i++;
}
}
},
destinationExit: function (event) {
var operation = document.DNDManager.currentDndOperation;
if (operation
&& operation.destination == event.target) {
if (operation.destination.dndExit)
event.target.dndExit();
operation.setDestination(null);
}
},
destinationOver: function (event) {
},
destinationDrop: function (event) {
var operation = document.DNDManager.currentDndOperation;
if (operation) {
window.removeEventListener("mouseup",
document.DNDManager.destinationDrop, false);
window.removeEventListener("mouseover",
document.DNDManager.destinationEnter, false);
window.removeEventListener("mousemove",
document.DNDManager.destinationOver, false);
window.removeEventListener("mouseout",
document.DNDManager.destinationExit, false);
if (operation.destination == event.target) {
if (operation.destination.dndExit) {
operation.destination.dndExit();
}
if (operation.destination.dndDrop) {
var data = null;
if (operation.source.dndDataForType)
data = operation.source.dndDataForType(operation.type);
var result = operation.destination.dndDrop(data);
if (operation.ghost) {
if (result)
operation.bustGhost();
else
operation.chaseGhost();
}
}
else
if (operation.ghost)
operation.chaseGhost();
} else {
if (operation.ghost)
operation.chaseGhost();
}
document.DNDManager.currentDndOperation = null;
}
},
currentDndOperation: null
}
/* DNDOperation */
document.DNDOperation = function (source, point) {
this.startPoint = point;
this.source = source;
if (source.dndTypes) {
this.types = source.dndTypes();
}
this.type = null;
this.destination = null;
if (source.dndGhost) {
var ghost = source.dndGhost();
ghost.style.position = "absolute;";
ghost.style.zIndex = 10000;
ghost.style.MozOpacity = 0.8;
document.body.appendChild(ghost);
this.ghost = ghost;
document.addEventListener("mousemove", this.moveGhost, false);
}
return this;
};
document.DNDOperation.prototype.setDestination = function(destination) {
this.destination = destination;
}
document.DNDOperation.prototype.moveGhost = function(event) {
var offsetX = event.clientX;
var offsetY = event.clientY;
if (document.DNDManager.currentDndOperation.ghost.ghostOffsetX)
offsetX += document.DNDManager.currentDndOperation.ghost.ghostOffsetX;
if (document.DNDManager.currentDndOperation.ghost.ghostOffsetY)
offsetY += document.DNDManager.currentDndOperation.ghost.ghostOffsetY;
document.DNDManager.currentDndOperation.ghost.style.left = offsetX + "px;";
document.DNDManager.currentDndOperation.ghost.style.top = offsetY + "px;";
}
document.DNDOperation.prototype.bustGhost = function() {
document._dyingOperation = this;
document.removeEventListener("mousemove", this.moveGhost, false);
this.ghost.bustStep = 10;
setTimeout("document._dyingOperation._fadeGhost();", 50);
}
document.DNDOperation.prototype.chaseGhost = function() {
document._dyingOperation = this;
document.removeEventListener("mousemove", this.moveGhost, false);
this.ghost.bustStep = 25;
this.ghost.chaseStep = 25;
this.ghost.style.overflow = "hidden;"
this.ghost.style.whiteSpace = "nowrap;";
this.ghost.chaseDeltaX = ((this.ghost.cascadeLeftOffset() - this.startPoint[0])
/ this.ghost.chaseStep);
this.ghost.chaseDeltaY = ((this.ghost.cascadeTopOffset() - this.startPoint[1])
/ this.ghost.chaseStep);
setTimeout("document._dyingOperation._chaseGhost();", 20);
}
document.DNDOperation.prototype._chaseGhost = function() {
if (this.ghost.chaseStep) {
var newLeft = this.ghost.cascadeLeftOffset() - this.ghost.chaseDeltaX;
var newTop = this.ghost.cascadeTopOffset() - this.ghost.chaseDeltaY;
this.ghost.style.MozOpacity = (0.04 * this.ghost.chaseStep);
this.ghost.style.left = newLeft + "px;";
this.ghost.style.top = newTop + "px;";
this.ghost.chaseStep--;
setTimeout("document._dyingOperation._chaseGhost();", 20);
}
else {
document.body.removeChild(this.ghost);
this.ghost = null;
}
}
document.DNDOperation.prototype._fadeGhost = function() {
if (this.ghost.bustStep) {
this.ghost.style.MozOpacity = (0.1 * this.ghost.bustStep);
this.ghost.style.width = (this.ghost.offsetWidth * .7) + "px;";
this.ghost.style.height = (this.ghost.offsetHeight * .7) + "px;";
this.ghost.bustStep--;
setTimeout("document._dyingOperation._fadeGhost();", 50);
}
else {
document.body.removeChild(this.ghost);
this.ghost = null;
}
}