DndToDojo.js 16 KB

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