source: Dev/trunk/src/client/dojox/mdnd/adapter/DndToDojo.js @ 483

Last change on this file since 483 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

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