DndToDojo.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. define("dojox/mdnd/adapter/DndToDojo", ["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/connect",
  2. "dojo/_base/window","dojo/_base/array","dojox/mdnd/PureSource","dojox/mdnd/LazyManager"],function(dojo){
  3. var dtd = dojo.declare(
  4. "dojox.mdnd.adapter.DndToDojo",
  5. null,
  6. {
  7. // summary:
  8. // Allow communication between an item of dojox D&D area to a target dojo.
  9. // _dojoList: Array
  10. // Array containing object references the dojo Target list
  11. _dojoList: null,
  12. // _currentDojoArea: DOMNode
  13. // Representing the current dojo area
  14. _currentDojoArea: null,
  15. // _dojoxManager: dojox.mdnd.AreaManager
  16. // The reference to the dojox AreaManager
  17. _dojoxManager: null,
  18. // _dragStartHandler: Object
  19. // Handle to keep start subscribe
  20. _dragStartHandler: null,
  21. // _dropHandler: Object
  22. // Handle to keep drop subscribe
  23. _dropHandler: null,
  24. // _moveHandler: Object
  25. // Handle to keep move subscribe
  26. _moveHandler: null,
  27. // _moveUpHandler: Object
  28. // Handle to kee move up subscribe
  29. _moveUpHandler: null,
  30. // _draggedNode: DOMNode
  31. // The current dragged node
  32. _draggedNode: null,
  33. constructor: function(){
  34. this._dojoList = [];
  35. this._currentDojoArea = null;
  36. this._dojoxManager = dojox.mdnd.areaManager();
  37. this._dragStartHandler = dojo.subscribe("/dojox/mdnd/drag/start", this, function(node, sourceArea, sourceDropIndex){
  38. this._draggedNode = node;
  39. this._moveHandler = dojo.connect(dojo.doc, "onmousemove", this, "onMouseMove");
  40. });
  41. this._dropHandler = dojo.subscribe("/dojox/mdnd/drop", this, function(node, targetArea, indexChild){
  42. if(this._currentDojoArea){
  43. dojo.publish("/dojox/mdnd/adapter/dndToDojo/cancel", [this._currentDojoArea.node, this._currentDojoArea.type, this._draggedNode, this.accept]);
  44. }
  45. this._draggedNode = null;
  46. this._currentDojoArea = null;
  47. dojo.disconnect(this._moveHandler);
  48. });
  49. },
  50. _getIndexDojoArea: function(/*node*/area){
  51. // summary:
  52. // Check if a dojo area is registered.
  53. // area: DOMNode
  54. // A node corresponding to the target dojo.
  55. // returns:
  56. // The index of area if it's registered else -1.
  57. // tags:
  58. // protected
  59. //console.log('dojox.mdnd.adapter.DndToDojo ::: _getIndexDojoArea');
  60. if(area){
  61. for(var i = 0, l = this._dojoList.length; i < l; i++){
  62. if(this._dojoList[i].node === area){
  63. return i;
  64. }
  65. }
  66. }
  67. return -1;
  68. },
  69. _initCoordinates: function(/*DOMNode*/area){
  70. // summary:
  71. // Initialize the coordinates of the target dojo.
  72. // area:
  73. // A registered DOM node.
  74. // returns:
  75. // An object which contains coordinates : *{x:0,y:,x1:0,y1:0}*
  76. // tags:
  77. // protected
  78. //console.log('dojox.mdnd.adapter.DndToDojo ::: _initCoordinates');
  79. if(area){
  80. var position = dojo.position(area, true),
  81. coords = {};
  82. coords.x = position.x
  83. coords.y = position.y
  84. coords.x1 = position.x + position.w;
  85. coords.y1 = position.y + position.h;
  86. return coords; // Object
  87. }
  88. return null;
  89. },
  90. register: function(/*DOMNode*/area, /*String*/ type,/*Boolean*/ dojoTarget){
  91. // summary:
  92. // Register a target dojo.
  93. // The target is represented by an object containing :
  94. // - the dojo area node
  95. // - the type reference to identify a group node
  96. // - the coords of the area to enable refresh position
  97. // area:
  98. // The DOM node which has to be registered.
  99. // type:
  100. // A String to identify the node.
  101. // dojoTarger:
  102. // True if the dojo D&D have to be enable when mouse is hover the registered target dojo.
  103. //console.log("dojox.mdnd.adapter.DndToDojo ::: registerDojoArea", area, type, dojoTarget);
  104. if(this._getIndexDojoArea(area) == -1){
  105. var coords = this._initCoordinates(area),
  106. object = {
  107. 'node': area,
  108. 'type': type,
  109. 'dojo': (dojoTarget)?dojoTarget:false,
  110. 'coords': coords
  111. };
  112. this._dojoList.push(object);
  113. // initialization of the _fakeSource to allow Dnd switching
  114. if(dojoTarget && !this._lazyManager){
  115. this._lazyManager = new dojox.mdnd.LazyManager();
  116. }
  117. }
  118. },
  119. unregisterByNode: function(/*DOMNode*/area){
  120. // summary:
  121. // Unregister a target dojo.
  122. // area:
  123. // The DOM node of target dojo.
  124. //console.log("dojox.mdnd.adapter.DndToDojo ::: unregisterByNode", area);
  125. var index = this._getIndexDojoArea(area);
  126. // if area is registered
  127. if(index != -1){
  128. this._dojoList.splice(index, 1);
  129. }
  130. },
  131. unregisterByType: function(/*String*/type){
  132. // summary:
  133. // Unregister several targets dojo having the same type passing in parameter.
  134. // type:
  135. // A String to identify dojo targets.
  136. //console.log("dojox.mdnd.adapter.DndToDojo ::: unregisterByType", type);
  137. if(type){
  138. var tempList = [];
  139. dojo.forEach(this._dojoList, function(item, i){
  140. if(item.type != type){
  141. tempList.push(item);
  142. }
  143. });
  144. this._dojoList = tempList;
  145. }
  146. },
  147. unregister: function(){
  148. // summary:
  149. // Unregister all targets dojo.
  150. //console.log("dojox.mdnd.adapter.DndToDojo ::: unregister");
  151. this._dojoList = [];
  152. },
  153. refresh: function(){
  154. // summary:
  155. // Refresh the coordinates of all registered dojo target.
  156. //console.log("dojox.mdnd.adapter.DndToDojo ::: refresh");
  157. var dojoList = this._dojoList;
  158. this.unregister();
  159. dojo.forEach(dojoList, function(dojo){
  160. dojo.coords = this._initCoordinates(dojo.node);
  161. }, this);
  162. this._dojoList = dojoList;
  163. },
  164. refreshByType: function(/*String*/ type){
  165. // summary:
  166. // Refresh the coordinates of registered dojo target with a specific type.
  167. // type:
  168. // A String to identify dojo targets.
  169. //console.log("dojox.mdnd.adapter.DndToDojo ::: refresh");
  170. var dojoList = this._dojoList;
  171. this.unregister();
  172. dojo.forEach(dojoList, function(dojo){
  173. if(dojo.type == type){
  174. dojo.coords = this._initCoordinates(dojo.node);
  175. }
  176. }, this);
  177. this._dojoList = dojoList;
  178. },
  179. _getHoverDojoArea: function(/*Object*/coords){
  180. // summary:
  181. // Check if the coordinates of the mouse is in a dojo target.
  182. // coords:
  183. // Coordinates of the mouse.
  184. // tags:
  185. // protected
  186. //console.log("dojox.mdnd.adapter.DndToDojo ::: _getHoverDojoArea");
  187. this._oldDojoArea = this._currentDojoArea;
  188. this._currentDojoArea = null;
  189. var x = coords.x;
  190. var y = coords.y;
  191. var length = this._dojoList.length;
  192. for(var i = 0; i < length; i++){
  193. var dojoArea = this._dojoList[i];
  194. var coordinates = dojoArea.coords;
  195. if(coordinates.x <= x && x <= coordinates.x1 && coordinates.y <= y && y <= coordinates.y1){
  196. this._currentDojoArea = dojoArea;
  197. break;
  198. }
  199. }
  200. },
  201. onMouseMove: function(/*DOMEvent*/e){
  202. // summary:
  203. // Call when the mouse moving after an onStartDrag of AreaManger.
  204. // Check if the coordinates of the mouse is in a dojo target.
  205. // e:
  206. // Event object.
  207. // tags:
  208. // callback
  209. //console.log("dojox.mdnd.adapter.DndToDojo ::: onMouseMove");
  210. var coords = {
  211. 'x': e.pageX,
  212. 'y': e.pageY
  213. };
  214. this._getHoverDojoArea(coords);
  215. if(this._currentDojoArea != this._oldDojoArea){
  216. if(this._currentDojoArea == null){
  217. this.onDragExit(e);
  218. }
  219. else if(this._oldDojoArea == null){
  220. this.onDragEnter(e);
  221. }
  222. else{
  223. this.onDragExit(e);
  224. this.onDragEnter(e);
  225. }
  226. }
  227. },
  228. isAccepted: function(/*DOMNode*/draggedNode, /*Object*/ target){
  229. // summary:
  230. // Return true if the dragged node is accepted.
  231. // This method has to be overwritten according to registered target.
  232. //console.log("dojox.mdnd.adapter.DndToDojo ::: isAccepted");
  233. return true;
  234. },
  235. onDragEnter: function(/*DOMEvent*/e){
  236. // summary:
  237. // Call when the mouse enters in a registered dojo target.
  238. // e:
  239. // The current Javascript Event.
  240. // tags:
  241. // callback
  242. //console.log("dojox.mdnd.adapter.DndToDojo ::: onDragEnter");
  243. // specific for drag and drop switch
  244. if(this._currentDojoArea.dojo){
  245. // disconnect
  246. dojo.disconnect(this._dojoxManager._dragItem.handlers.pop());
  247. dojo.disconnect(this._dojoxManager._dragItem.handlers.pop());
  248. //disconnect onmousemove of moveable item
  249. //console.info("before",this._dojoxManager._dragItem.item.events.pop());
  250. dojo.disconnect(this._dojoxManager._dragItem.item.events.pop());
  251. dojo.body().removeChild(this._dojoxManager._cover);
  252. dojo.body().removeChild(this._dojoxManager._cover2);
  253. var node = this._dojoxManager._dragItem.item.node;
  254. // hide dragNode :
  255. // disconnect the dojoDndAdapter if it's initialize
  256. if(dojox.mdnd.adapter._dndFromDojo){
  257. dojox.mdnd.adapter._dndFromDojo.unsubscribeDnd();
  258. }
  259. dojo.style(node, {
  260. 'position': "relative",
  261. 'top': '0',
  262. 'left': '0'
  263. });
  264. // launch the drag and drop Dojo.
  265. this._lazyManager.startDrag(e, node);
  266. var handle = dojo.connect(this._lazyManager.manager, "overSource", this, function(){
  267. dojo.disconnect(handle);
  268. if(this._lazyManager.manager.canDropFlag){
  269. // remove dropIndicator
  270. this._dojoxManager._dropIndicator.node.style.display = "none";
  271. }
  272. });
  273. this.cancelHandler = dojo.subscribe("/dnd/cancel", this, function(){
  274. var moveableItem = this._dojoxManager._dragItem.item;
  275. // connect onmousemove of moveable item
  276. // need to reconnect the onmousedown of movable class.
  277. moveableItem.events = [
  278. dojo.connect(moveableItem.handle, "onmousedown", moveableItem, "onMouseDown")
  279. ];
  280. // replace the cover and the dragNode in the cover.
  281. dojo.body().appendChild(this._dojoxManager._cover);
  282. dojo.body().appendChild(this._dojoxManager._cover2);
  283. this._dojoxManager._cover.appendChild(moveableItem.node);
  284. var objectArea = this._dojoxManager._areaList[this._dojoxManager._sourceIndexArea];
  285. var dropIndex = this._dojoxManager._sourceDropIndex;
  286. var nodeRef = null;
  287. if(dropIndex != objectArea.items.length
  288. && dropIndex != -1){
  289. nodeRef = objectArea.items[this._dojoxManager._sourceDropIndex].item.node;
  290. }
  291. if(this._dojoxManager._dropIndicator.node.style.display == "none"){
  292. this._dojoxManager._dropIndicator.node.style.display == "";
  293. }
  294. this._dojoxManager._dragItem.handlers.push(dojo.connect(this._dojoxManager._dragItem.item, "onDrag", this._dojoxManager, "onDrag"));
  295. this._dojoxManager._dragItem.handlers.push(dojo.connect(this._dojoxManager._dragItem.item, "onDragEnd", this._dojoxManager, "onDrop"));
  296. this._draggedNode.style.display = "";
  297. this._dojoxManager.onDrop(this._draggedNode);
  298. dojo.unsubscribe(this.cancelHandler);
  299. dojo.unsubscribe(this.dropHandler);
  300. if(dojox.mdnd.adapter._dndFromDojo){
  301. dojox.mdnd.adapter._dndFromDojo.subscribeDnd();
  302. }
  303. });
  304. this.dropHandler = dojo.subscribe("/dnd/drop/before", this, function(params){
  305. dojo.unsubscribe(this.cancelHandler);
  306. dojo.unsubscribe(this.dropHandler);
  307. this.onDrop();
  308. });
  309. }
  310. else{
  311. this.accept = this.isAccepted(this._dojoxManager._dragItem.item.node, this._currentDojoArea);
  312. if(this.accept){
  313. // disconnect
  314. dojo.disconnect(this._dojoxManager._dragItem.handlers.pop());
  315. dojo.disconnect(this._dojoxManager._dragItem.handlers.pop());
  316. // remove dropIndicator
  317. this._dojoxManager._dropIndicator.node.style.display = "none";
  318. if(!this._moveUpHandler){
  319. this._moveUpHandler = dojo.connect(dojo.doc, "onmouseup", this, "onDrop");
  320. }
  321. }
  322. }
  323. // publish a topic
  324. dojo.publish("/dojox/mdnd/adapter/dndToDojo/over",[this._currentDojoArea.node, this._currentDojoArea.type, this._draggedNode, this.accept]);
  325. },
  326. onDragExit: function(/*DOMEvent*/e){
  327. // summary:
  328. // Call when the mouse exit of a registered dojo target.
  329. // e:
  330. // current javscript event
  331. //console.log("dojox.mdnd.adapter.DndToDojo ::: onDragExit",e, this._dojoxManager._dragItem.item);
  332. // set the old height of dropIndicator.
  333. if(this._oldDojoArea.dojo){
  334. // unsubscribe the topic /dnd/cancel and /dnd/drop/before
  335. dojo.unsubscribe(this.cancelHandler);
  336. dojo.unsubscribe(this.dropHandler);
  337. // launch Drag and Drop
  338. var moveableItem = this._dojoxManager._dragItem.item;
  339. // connect onmousemove of moveable item
  340. this._dojoxManager._dragItem.item.events.push(dojo.connect(
  341. moveableItem.node.ownerDocument,
  342. "onmousemove",
  343. moveableItem,
  344. "onMove"
  345. ));
  346. // replace the cover and the dragNode in the cover.
  347. dojo.body().appendChild(this._dojoxManager._cover);
  348. dojo.body().appendChild(this._dojoxManager._cover2);
  349. this._dojoxManager._cover.appendChild(moveableItem.node);
  350. // fix style :
  351. var style = moveableItem.node.style;
  352. style.position = "absolute";
  353. style.left = (moveableItem.offsetDrag.l + e.pageX)+"px";
  354. style.top = (moveableItem.offsetDrag.t + e.pageX)+"px";
  355. style.display = "";
  356. // stop dojoDrag
  357. this._lazyManager.cancelDrag();
  358. // reconnect the dndFromDojo
  359. if(dojox.mdnd.adapter._dndFromDojo){
  360. dojox.mdnd.adapter._dndFromDojo.subscribeDnd();
  361. }
  362. if(this._dojoxManager._dropIndicator.node.style.display == "none"){
  363. this._dojoxManager._dropIndicator.node.style.display = "";
  364. }
  365. // reconnect the areaManager.
  366. this._dojoxManager._dragItem.handlers.push(dojo.connect(this._dojoxManager._dragItem.item, "onDrag", this._dojoxManager, "onDrag"));
  367. this._dojoxManager._dragItem.handlers.push(dojo.connect(this._dojoxManager._dragItem.item, "onDragEnd", this._dojoxManager, "onDrop"));
  368. this._dojoxManager._dragItem.item.onMove(e);
  369. }
  370. else{
  371. if(this.accept){
  372. // disconnect the mouseUp event.
  373. if(this._moveUpHandler){
  374. dojo.disconnect(this._moveUpHandler);
  375. this._moveUpHandler = null;
  376. }
  377. // redisplay dropIndicator
  378. if(this._dojoxManager._dropIndicator.node.style.display == "none"){
  379. this._dojoxManager._dropIndicator.node.style.display = "";
  380. }
  381. // reconnect the areaManager.
  382. this._dojoxManager._dragItem.handlers.push(dojo.connect(this._dojoxManager._dragItem.item, "onDrag", this._dojoxManager, "onDrag"));
  383. this._dojoxManager._dragItem.handlers.push(dojo.connect(this._dojoxManager._dragItem.item, "onDragEnd", this._dojoxManager, "onDrop"));
  384. this._dojoxManager._dragItem.item.onMove(e);
  385. }
  386. }
  387. // publish a topic
  388. dojo.publish("/dojox/mdnd/adapter/dndToDojo/out",[this._oldDojoArea.node, this._oldDojoArea.type, this._draggedNode, this.accept]);
  389. },
  390. onDrop: function(/*DOMEvent*/e){
  391. // summary:
  392. // Called when an onmouseup event is loaded on a registered target dojo.
  393. // e:
  394. // Event object.
  395. // console.log("dojox.mdnd.adapter.DndToDojo ::: onDrop", this._currentDojoArea);
  396. if(this._currentDojoArea.dojo){
  397. // reconnect the dojoDndAdapter
  398. if(dojox.mdnd.adapter._dndFromDojo){
  399. dojox.mdnd.adapter._dndFromDojo.subscribeDnd();
  400. }
  401. }
  402. if(this._dojoxManager._dropIndicator.node.style.display == "none"){
  403. this._dojoxManager._dropIndicator.node.style.display = "";
  404. }
  405. // remove the cover
  406. if(this._dojoxManager._cover.parentNode && this._dojoxManager._cover.parentNode.nodeType == 1){
  407. dojo.body().removeChild(this._dojoxManager._cover);
  408. dojo.body().removeChild(this._dojoxManager._cover2);
  409. }
  410. // remove draggedNode of target :
  411. if(this._draggedNode.parentNode == this._dojoxManager._cover){
  412. this._dojoxManager._cover.removeChild(this._draggedNode);
  413. }
  414. dojo.disconnect(this._moveHandler);
  415. dojo.disconnect(this._moveUpHandler);
  416. this._moveHandler = this._moveUpHandler = null;
  417. dojo.publish("/dojox/mdnd/adapter/dndToDojo/drop", [this._draggedNode, this._currentDojoArea.node, this._currentDojoArea.type]);
  418. dojo.removeClass(this._draggedNode, "dragNode");
  419. var style = this._draggedNode.style;
  420. style.position = "relative";
  421. style.left = "0";
  422. style.top = "0";
  423. style.width = "auto";
  424. dojo.forEach(this._dojoxManager._dragItem.handlers, dojo.disconnect);
  425. this._dojoxManager._deleteMoveableItem(this._dojoxManager._dragItem);
  426. this._draggedNode = null;
  427. this._currentDojoArea = null;
  428. // reset of area manager.
  429. this._dojoxManager._resetAfterDrop();
  430. }
  431. });
  432. dojox.mdnd.adapter._dndToDojo = null;
  433. dojox.mdnd.adapter.dndToDojo = function(){
  434. // summary:
  435. // returns the current areaManager, creates one if it is not created yet
  436. if(!dojox.mdnd.adapter._dndToDojo){
  437. dojox.mdnd.adapter._dndToDojo = new dojox.mdnd.adapter.DndToDojo();
  438. }
  439. return dojox.mdnd.adapter._dndToDojo; // Object
  440. };
  441. return dtd;
  442. });