/*
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
if(!dojo._hasResource["dojox.mdnd.adapter.DndToDojo"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojox.mdnd.adapter.DndToDojo"] = true;
dojo.provide("dojox.mdnd.adapter.DndToDojo");
dojo.require("dojox.mdnd.PureSource");
dojo.require("dojox.mdnd.LazyManager");
dojo.declare(
"dojox.mdnd.adapter.DndToDojo",
null,
{
// summary:
// Allow communication between an item of dojox D&D area to a target dojo.
// _dojoList: Array
// Array containing object references the dojo Target list
_dojoList: null,
// _currentDojoArea: DOMNode
// Representing the current dojo area
_currentDojoArea: null,
// _dojoxManager: dojox.mdnd.AreaManager
// The reference to the dojox AreaManager
_dojoxManager: null,
// _dragStartHandler: Object
// Handle to keep start subscribe
_dragStartHandler: null,
// _dropHandler: Object
// Handle to keep drop subscribe
_dropHandler: null,
// _moveHandler: Object
// Handle to keep move subscribe
_moveHandler: null,
// _moveUpHandler: Object
// Handle to kee move up subscribe
_moveUpHandler: null,
// _draggedNode: DOMNode
// The current dragged node
_draggedNode: null,
constructor: function(){
this._dojoList = [];
this._currentDojoArea = null;
this._dojoxManager = dojox.mdnd.areaManager();
this._dragStartHandler = dojo.subscribe("/dojox/mdnd/drag/start", this, function(node, sourceArea, sourceDropIndex){
this._draggedNode = node;
this._moveHandler = dojo.connect(dojo.doc, "onmousemove", this, "onMouseMove");
});
this._dropHandler = dojo.subscribe("/dojox/mdnd/drop", this, function(node, targetArea, indexChild){
if(this._currentDojoArea){
dojo.publish("/dojox/mdnd/adapter/dndToDojo/cancel", [this._currentDojoArea.node, this._currentDojoArea.type, this._draggedNode, this.accept]);
}
this._draggedNode = null;
this._currentDojoArea = null;
dojo.disconnect(this._moveHandler);
});
},
_getIndexDojoArea: function(/*node*/area){
// summary:
// Check if a dojo area is registered.
// area: DOMNode
// A node corresponding to the target dojo.
// returns:
// The index of area if it's registered else -1.
// tags:
// protected
//console.log('dojox.mdnd.adapter.DndToDojo ::: _getIndexDojoArea');
if(area){
for(var i = 0, l = this._dojoList.length; i < l; i++){
if(this._dojoList[i].node === area){
return i;
}
}
}
return -1;
},
_initCoordinates: function(/*DOMNode*/area){
// summary:
// Initialize the coordinates of the target dojo.
// area:
// A registered DOM node.
// returns:
// An object which contains coordinates : *{x:0,y:,x1:0,y1:0}*
// tags:
// protected
//console.log('dojox.mdnd.adapter.DndToDojo ::: _initCoordinates');
if(area){
var position = dojo.position(area, true),
coords = {};
coords.x = position.x
coords.y = position.y
coords.x1 = position.x + position.w;
coords.y1 = position.y + position.h;
return coords; // Object
}
return null;
},
register: function(/*DOMNode*/area, /*String*/ type,/*Boolean*/ dojoTarget){
// summary:
// Register a target dojo.
// The target is represented by an object containing :
// - the dojo area node
// - the type reference to identify a group node
// - the coords of the area to enable refresh position
// area:
// The DOM node which has to be registered.
// type:
// A String to identify the node.
// dojoTarger:
// True if the dojo D&D have to be enable when mouse is hover the registered target dojo.
//console.log("dojox.mdnd.adapter.DndToDojo ::: registerDojoArea", area, type, dojoTarget);
if(this._getIndexDojoArea(area) == -1){
var coords = this._initCoordinates(area),
object = {
'node': area,
'type': type,
'dojo': (dojoTarget)?dojoTarget:false,
'coords': coords
};
this._dojoList.push(object);
// initialization of the _fakeSource to allow Dnd switching
if(dojoTarget && !this._lazyManager){
this._lazyManager = new dojox.mdnd.LazyManager();
}
}
},
unregisterByNode: function(/*DOMNode*/area){
// summary:
// Unregister a target dojo.
// area:
// The DOM node of target dojo.
//console.log("dojox.mdnd.adapter.DndToDojo ::: unregisterByNode", area);
var index = this._getIndexDojoArea(area);
// if area is registered
if(index != -1){
this._dojoList.splice(index, 1);
}
},
unregisterByType: function(/*String*/type){
// summary:
// Unregister several targets dojo having the same type passing in parameter.
// type:
// A String to identify dojo targets.
//console.log("dojox.mdnd.adapter.DndToDojo ::: unregisterByType", type);
if(type){
var tempList = [];
dojo.forEach(this._dojoList, function(item, i){
if(item.type != type){
tempList.push(item);
}
});
this._dojoList = tempList;
}
},
unregister: function(){
// summary:
// Unregister all targets dojo.
//console.log("dojox.mdnd.adapter.DndToDojo ::: unregister");
this._dojoList = [];
},
refresh: function(){
// summary:
// Refresh the coordinates of all registered dojo target.
//console.log("dojox.mdnd.adapter.DndToDojo ::: refresh");
var dojoList = this._dojoList;
this.unregister();
dojo.forEach(dojoList, function(dojo){
dojo.coords = this._initCoordinates(dojo.node);
}, this);
this._dojoList = dojoList;
},
refreshByType: function(/*String*/ type){
// summary:
// Refresh the coordinates of registered dojo target with a specific type.
// type:
// A String to identify dojo targets.
//console.log("dojox.mdnd.adapter.DndToDojo ::: refresh");
var dojoList = this._dojoList;
this.unregister();
dojo.forEach(dojoList, function(dojo){
if(dojo.type == type){
dojo.coords = this._initCoordinates(dojo.node);
}
}, this);
this._dojoList = dojoList;
},
_getHoverDojoArea: function(/*Object*/coords){
// summary:
// Check if the coordinates of the mouse is in a dojo target.
// coords:
// Coordinates of the mouse.
// tags:
// protected
//console.log("dojox.mdnd.adapter.DndToDojo ::: _getHoverDojoArea");
this._oldDojoArea = this._currentDojoArea;
this._currentDojoArea = null;
var x = coords.x;
var y = coords.y;
var length = this._dojoList.length;
for(var i = 0; i < length; i++){
var dojoArea = this._dojoList[i];
var coordinates = dojoArea.coords;
if(coordinates.x <= x && x <= coordinates.x1 && coordinates.y <= y && y <= coordinates.y1){
this._currentDojoArea = dojoArea;
break;
}
}
},
onMouseMove: function(/*DOMEvent*/e){
// summary:
// Call when the mouse moving after an onStartDrag of AreaManger.
// Check if the coordinates of the mouse is in a dojo target.
// e:
// Event object.
// tags:
// callback
//console.log("dojox.mdnd.adapter.DndToDojo ::: onMouseMove");
var coords = {
'x': e.pageX,
'y': e.pageY
};
this._getHoverDojoArea(coords);
if(this._currentDojoArea != this._oldDojoArea){
if(this._currentDojoArea == null){
this.onDragExit(e);
}
else if(this._oldDojoArea == null){
this.onDragEnter(e);
}
else{
this.onDragExit(e);
this.onDragEnter(e);
}
}
},
isAccepted: function(/*DOMNode*/draggedNode, /*Object*/ target){
// summary:
// Return true if the dragged node is accepted.
// This method has to be overwritten according to registered target.
//console.log("dojox.mdnd.adapter.DndToDojo ::: isAccepted");
return true;
},
onDragEnter: function(/*DOMEvent*/e){
// summary:
// Call when the mouse enters in a registered dojo target.
// e:
// The current Javascript Event.
// tags:
// callback
//console.log("dojox.mdnd.adapter.DndToDojo ::: onDragEnter");
// specific for drag and drop switch
if(this._currentDojoArea.dojo){
// disconnect
dojo.disconnect(this._dojoxManager._dragItem.handlers.pop());
dojo.disconnect(this._dojoxManager._dragItem.handlers.pop());
//disconnect onmousemove of moveable item
//console.info("before",this._dojoxManager._dragItem.item.events.pop());
dojo.disconnect(this._dojoxManager._dragItem.item.events.pop());
dojo.body().removeChild(this._dojoxManager._cover);
dojo.body().removeChild(this._dojoxManager._cover2);
var node = this._dojoxManager._dragItem.item.node;
// hide dragNode :
// disconnect the dojoDndAdapter if it's initialize
if(dojox.mdnd.adapter._dndFromDojo){
dojox.mdnd.adapter._dndFromDojo.unsubscribeDnd();
}
dojo.style(node, {
'position': "relative",
'top': '0',
'left': '0'
});
// launch the drag and drop Dojo.
this._lazyManager.startDrag(e, node);
var handle = dojo.connect(this._lazyManager.manager, "overSource", this, function(){
dojo.disconnect(handle);
if(this._lazyManager.manager.canDropFlag){
// remove dropIndicator
this._dojoxManager._dropIndicator.node.style.display = "none";
}
});
this.cancelHandler = dojo.subscribe("/dnd/cancel", this, function(){
var moveableItem = this._dojoxManager._dragItem.item;
// connect onmousemove of moveable item
// need to reconnect the onmousedown of movable class.
moveableItem.events = [
dojo.connect(moveableItem.handle, "onmousedown", moveableItem, "onMouseDown")
];
// replace the cover and the dragNode in the cover.
dojo.body().appendChild(this._dojoxManager._cover);
dojo.body().appendChild(this._dojoxManager._cover2);
this._dojoxManager._cover.appendChild(moveableItem.node);
var objectArea = this._dojoxManager._areaList[this._dojoxManager._sourceIndexArea];
var dropIndex = this._dojoxManager._sourceDropIndex;
var nodeRef = null;
if(dropIndex != objectArea.items.length
&& dropIndex != -1){
nodeRef = objectArea.items[this._dojoxManager._sourceDropIndex].item.node;
}
if(this._dojoxManager._dropIndicator.node.style.display == "none"){
this._dojoxManager._dropIndicator.node.style.display == "";
}
this._dojoxManager._dragItem.handlers.push(dojo.connect(this._dojoxManager._dragItem.item, "onDrag", this._dojoxManager, "onDrag"));
this._dojoxManager._dragItem.handlers.push(dojo.connect(this._dojoxManager._dragItem.item, "onDragEnd", this._dojoxManager, "onDrop"));
this._draggedNode.style.display = "";
this._dojoxManager.onDrop(this._draggedNode);
dojo.unsubscribe(this.cancelHandler);
dojo.unsubscribe(this.dropHandler);
if(dojox.mdnd.adapter._dndFromDojo){
dojox.mdnd.adapter._dndFromDojo.subscribeDnd();
}
});
this.dropHandler = dojo.subscribe("/dnd/drop/before", this, function(params){
dojo.unsubscribe(this.cancelHandler);
dojo.unsubscribe(this.dropHandler);
this.onDrop();
});
}
else{
this.accept = this.isAccepted(this._dojoxManager._dragItem.item.node, this._currentDojoArea);
if(this.accept){
// disconnect
dojo.disconnect(this._dojoxManager._dragItem.handlers.pop());
dojo.disconnect(this._dojoxManager._dragItem.handlers.pop());
// remove dropIndicator
this._dojoxManager._dropIndicator.node.style.display = "none";
if(!this._moveUpHandler){
this._moveUpHandler = dojo.connect(dojo.doc, "onmouseup", this, "onDrop");
}
}
}
// publish a topic
dojo.publish("/dojox/mdnd/adapter/dndToDojo/over",[this._currentDojoArea.node, this._currentDojoArea.type, this._draggedNode, this.accept]);
},
onDragExit: function(/*DOMEvent*/e){
// summary:
// Call when the mouse exit of a registered dojo target.
// e:
// current javscript event
//console.log("dojox.mdnd.adapter.DndToDojo ::: onDragExit",e, this._dojoxManager._dragItem.item);
// set the old height of dropIndicator.
if(this._oldDojoArea.dojo){
// unsubscribe the topic /dnd/cancel and /dnd/drop/before
dojo.unsubscribe(this.cancelHandler);
dojo.unsubscribe(this.dropHandler);
// launch Drag and Drop
var moveableItem = this._dojoxManager._dragItem.item;
// connect onmousemove of moveable item
this._dojoxManager._dragItem.item.events.push(dojo.connect(
moveableItem.node.ownerDocument,
"onmousemove",
moveableItem,
"onMove"
));
// replace the cover and the dragNode in the cover.
dojo.body().appendChild(this._dojoxManager._cover);
dojo.body().appendChild(this._dojoxManager._cover2);
this._dojoxManager._cover.appendChild(moveableItem.node);
// fix style :
var style = moveableItem.node.style;
style.position = "absolute";
style.left = (moveableItem.offsetDrag.l + e.pageX)+"px";
style.top = (moveableItem.offsetDrag.t + e.pageX)+"px";
style.display = "";
// stop dojoDrag
this._lazyManager.cancelDrag();
// reconnect the dndFromDojo
if(dojox.mdnd.adapter._dndFromDojo){
dojox.mdnd.adapter._dndFromDojo.subscribeDnd();
}
if(this._dojoxManager._dropIndicator.node.style.display == "none"){
this._dojoxManager._dropIndicator.node.style.display = "";
}
// reconnect the areaManager.
this._dojoxManager._dragItem.handlers.push(dojo.connect(this._dojoxManager._dragItem.item, "onDrag", this._dojoxManager, "onDrag"));
this._dojoxManager._dragItem.handlers.push(dojo.connect(this._dojoxManager._dragItem.item, "onDragEnd", this._dojoxManager, "onDrop"));
this._dojoxManager._dragItem.item.onMove(e);
}
else{
if(this.accept){
// disconnect the mouseUp event.
if(this._moveUpHandler){
dojo.disconnect(this._moveUpHandler);
this._moveUpHandler = null;
}
// redisplay dropIndicator
if(this._dojoxManager._dropIndicator.node.style.display == "none"){
this._dojoxManager._dropIndicator.node.style.display = "";
}
// reconnect the areaManager.
this._dojoxManager._dragItem.handlers.push(dojo.connect(this._dojoxManager._dragItem.item, "onDrag", this._dojoxManager, "onDrag"));
this._dojoxManager._dragItem.handlers.push(dojo.connect(this._dojoxManager._dragItem.item, "onDragEnd", this._dojoxManager, "onDrop"));
this._dojoxManager._dragItem.item.onMove(e);
}
}
// publish a topic
dojo.publish("/dojox/mdnd/adapter/dndToDojo/out",[this._oldDojoArea.node, this._oldDojoArea.type, this._draggedNode, this.accept]);
},
onDrop: function(/*DOMEvent*/e){
// summary:
// Called when an onmouseup event is loaded on a registered target dojo.
// e:
// Event object.
// console.log("dojox.mdnd.adapter.DndToDojo ::: onDrop", this._currentDojoArea);
if(this._currentDojoArea.dojo){
// reconnect the dojoDndAdapter
if(dojox.mdnd.adapter._dndFromDojo){
dojox.mdnd.adapter._dndFromDojo.subscribeDnd();
}
}
if(this._dojoxManager._dropIndicator.node.style.display == "none"){
this._dojoxManager._dropIndicator.node.style.display = "";
}
// remove the cover
if(this._dojoxManager._cover.parentNode && this._dojoxManager._cover.parentNode.nodeType == 1){
dojo.body().removeChild(this._dojoxManager._cover);
dojo.body().removeChild(this._dojoxManager._cover2);
}
// remove draggedNode of target :
if(this._draggedNode.parentNode == this._dojoxManager._cover){
this._dojoxManager._cover.removeChild(this._draggedNode);
}
dojo.disconnect(this._moveHandler);
dojo.disconnect(this._moveUpHandler);
this._moveHandler = this._moveUpHandler = null;
dojo.publish("/dojox/mdnd/adapter/dndToDojo/drop", [this._draggedNode, this._currentDojoArea.node, this._currentDojoArea.type]);
dojo.removeClass(this._draggedNode, "dragNode");
var style = this._draggedNode.style;
style.position = "relative";
style.left = "0";
style.top = "0";
style.width = "auto";
dojo.forEach(this._dojoxManager._dragItem.handlers, dojo.disconnect);
this._dojoxManager._deleteMoveableItem(this._dojoxManager._dragItem);
this._draggedNode = null;
this._currentDojoArea = null;
// reset of area manager.
this._dojoxManager._resetAfterDrop();
}
});
dojox.mdnd.adapter._dndToDojo = null;
dojox.mdnd.adapter.dndToDojo = function(){
// summary:
// returns the current areaManager, creates one if it is not created yet
if(!dojox.mdnd.adapter._dndToDojo){
dojox.mdnd.adapter._dndToDojo = new dojox.mdnd.adapter.DndToDojo();
}
return dojox.mdnd.adapter._dndToDojo; // Object
};
}