]> git.wh0rd.org Git - tt-rss.git/blob - lib/dojo/dnd/Manager.js.uncompressed.js
upgrade dojo to 1.8.3 (refs #570)
[tt-rss.git] / lib / dojo / dnd / Manager.js.uncompressed.js
1 define("dojo/dnd/Manager", [
2         "../_base/array",  "../_base/declare", "../_base/event", "../_base/lang", "../_base/window",
3         "../dom-class", "../Evented", "../has", "../keys", "../on", "../topic", "../touch",
4         "./common", "./autoscroll", "./Avatar"
5 ], function(array, declare, event, lang, win, domClass, Evented, has, keys, on, topic, touch,
6         dnd, autoscroll, Avatar){
7
8 // module:
9 //              dojo/dnd/Manager
10
11 var Manager = declare("dojo.dnd.Manager", [Evented], {
12         // summary:
13         //              the manager of DnD operations (usually a singleton)
14         constructor: function(){
15                 this.avatar  = null;
16                 this.source = null;
17                 this.nodes = [];
18                 this.copy  = true;
19                 this.target = null;
20                 this.canDropFlag = false;
21                 this.events = [];
22         },
23
24         // avatar's offset from the mouse
25         OFFSET_X: has("touch") ? 0 : 16,
26         OFFSET_Y: has("touch") ? -64 : 16,
27
28         // methods
29         overSource: function(source){
30                 // summary:
31                 //              called when a source detected a mouse-over condition
32                 // source: Object
33                 //              the reporter
34                 if(this.avatar){
35                         this.target = (source && source.targetState != "Disabled") ? source : null;
36                         this.canDropFlag = Boolean(this.target);
37                         this.avatar.update();
38                 }
39                 topic.publish("/dnd/source/over", source);
40         },
41         outSource: function(source){
42                 // summary:
43                 //              called when a source detected a mouse-out condition
44                 // source: Object
45                 //              the reporter
46                 if(this.avatar){
47                         if(this.target == source){
48                                 this.target = null;
49                                 this.canDropFlag = false;
50                                 this.avatar.update();
51                                 topic.publish("/dnd/source/over", null);
52                         }
53                 }else{
54                         topic.publish("/dnd/source/over", null);
55                 }
56         },
57         startDrag: function(source, nodes, copy){
58                 // summary:
59                 //              called to initiate the DnD operation
60                 // source: Object
61                 //              the source which provides items
62                 // nodes: Array
63                 //              the list of transferred items
64                 // copy: Boolean
65                 //              copy items, if true, move items otherwise
66
67                 // Tell autoscroll that a drag is starting
68                 autoscroll.autoScrollStart(win.doc);
69
70                 this.source = source;
71                 this.nodes  = nodes;
72                 this.copy   = Boolean(copy); // normalizing to true boolean
73                 this.avatar = this.makeAvatar();
74                 win.body().appendChild(this.avatar.node);
75                 topic.publish("/dnd/start", source, nodes, this.copy);
76                 this.events = [
77                         on(win.doc, touch.move, lang.hitch(this, "onMouseMove")),
78                         on(win.doc, touch.release,   lang.hitch(this, "onMouseUp")),
79                         on(win.doc, "keydown",   lang.hitch(this, "onKeyDown")),
80                         on(win.doc, "keyup",     lang.hitch(this, "onKeyUp")),
81                         // cancel text selection and text dragging
82                         on(win.doc, "dragstart",   event.stop),
83                         on(win.body(), "selectstart", event.stop)
84                 ];
85                 var c = "dojoDnd" + (copy ? "Copy" : "Move");
86                 domClass.add(win.body(), c);
87         },
88         canDrop: function(flag){
89                 // summary:
90                 //              called to notify if the current target can accept items
91                 var canDropFlag = Boolean(this.target && flag);
92                 if(this.canDropFlag != canDropFlag){
93                         this.canDropFlag = canDropFlag;
94                         this.avatar.update();
95                 }
96         },
97         stopDrag: function(){
98                 // summary:
99                 //              stop the DnD in progress
100                 domClass.remove(win.body(), ["dojoDndCopy", "dojoDndMove"]);
101                 array.forEach(this.events, function(handle){ handle.remove(); });
102                 this.events = [];
103                 this.avatar.destroy();
104                 this.avatar = null;
105                 this.source = this.target = null;
106                 this.nodes = [];
107         },
108         makeAvatar: function(){
109                 // summary:
110                 //              makes the avatar; it is separate to be overwritten dynamically, if needed
111                 return new Avatar(this);
112         },
113         updateAvatar: function(){
114                 // summary:
115                 //              updates the avatar; it is separate to be overwritten dynamically, if needed
116                 this.avatar.update();
117         },
118
119         // mouse event processors
120         onMouseMove: function(e){
121                 // summary:
122                 //              event processor for onmousemove
123                 // e: Event
124                 //              mouse event
125                 var a = this.avatar;
126                 if(a){
127                         autoscroll.autoScrollNodes(e);
128                         //autoscroll.autoScroll(e);
129                         var s = a.node.style;
130                         s.left = (e.pageX + this.OFFSET_X) + "px";
131                         s.top  = (e.pageY + this.OFFSET_Y) + "px";
132                         var copy = Boolean(this.source.copyState(dnd.getCopyKeyState(e)));
133                         if(this.copy != copy){
134                                 this._setCopyStatus(copy);
135                         }
136                 }
137                 if(has("touch")){
138                         // Prevent page from scrolling so that user can drag instead.
139                         e.preventDefault();
140                 }
141         },
142         onMouseUp: function(e){
143                 // summary:
144                 //              event processor for onmouseup
145                 // e: Event
146                 //              mouse event
147                 if(this.avatar){
148                         if(this.target && this.canDropFlag){
149                                 var copy = Boolean(this.source.copyState(dnd.getCopyKeyState(e)));
150                                 topic.publish("/dnd/drop/before", this.source, this.nodes, copy, this.target, e);
151                                 topic.publish("/dnd/drop", this.source, this.nodes, copy, this.target, e);
152                         }else{
153                                 topic.publish("/dnd/cancel");
154                         }
155                         this.stopDrag();
156                 }
157         },
158
159         // keyboard event processors
160         onKeyDown: function(e){
161                 // summary:
162                 //              event processor for onkeydown:
163                 //              watching for CTRL for copy/move status, watching for ESCAPE to cancel the drag
164                 // e: Event
165                 //              keyboard event
166                 if(this.avatar){
167                         switch(e.keyCode){
168                                 case keys.CTRL:
169                                         var copy = Boolean(this.source.copyState(true));
170                                         if(this.copy != copy){
171                                                 this._setCopyStatus(copy);
172                                         }
173                                         break;
174                                 case keys.ESCAPE:
175                                         topic.publish("/dnd/cancel");
176                                         this.stopDrag();
177                                         break;
178                         }
179                 }
180         },
181         onKeyUp: function(e){
182                 // summary:
183                 //              event processor for onkeyup, watching for CTRL for copy/move status
184                 // e: Event
185                 //              keyboard event
186                 if(this.avatar && e.keyCode == keys.CTRL){
187                         var copy = Boolean(this.source.copyState(false));
188                         if(this.copy != copy){
189                                 this._setCopyStatus(copy);
190                         }
191                 }
192         },
193
194         // utilities
195         _setCopyStatus: function(copy){
196                 // summary:
197                 //              changes the copy status
198                 // copy: Boolean
199                 //              the copy status
200                 this.copy = copy;
201                 this.source._markDndStatus(this.copy);
202                 this.updateAvatar();
203                 domClass.replace(win.body(),
204                         "dojoDnd" + (this.copy ? "Copy" : "Move"),
205                         "dojoDnd" + (this.copy ? "Move" : "Copy"));
206         }
207 });
208
209 // dnd._manager:
210 //              The manager singleton variable. Can be overwritten if needed.
211 dnd._manager = null;
212
213 Manager.manager = dnd.manager = function(){
214         // summary:
215         //              Returns the current DnD manager.  Creates one if it is not created yet.
216         if(!dnd._manager){
217                 dnd._manager = new Manager();
218         }
219         return dnd._manager;    // Object
220 };
221
222 return Manager;
223 });