source: Dev/branches/rest-dojo-ui/client/dojox/mdnd/adapter/DndToDojo.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

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