source: Dev/trunk/src/client/dojo/dnd/Mover.js @ 529

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

Added Dojo 1.9.3 release.

File size: 4.2 KB
Line 
1define([
2        "../_base/array", "../_base/declare", "../_base/lang", "../sniff", "../_base/window",
3        "../dom", "../dom-geometry", "../dom-style", "../Evented", "../on", "../touch", "./common", "./autoscroll"
4], function(array, declare, lang, has, win, dom, domGeom, domStyle, Evented, on, touch, dnd, autoscroll){
5
6// module:
7//              dojo/dnd/Mover
8
9return declare("dojo.dnd.Mover", [Evented], {
10        // summary:
11        //              an object which makes a node follow the mouse, or touch-drag on touch devices.
12        //              Used as a default mover, and as a base class for custom movers.
13
14        constructor: function(node, e, host){
15                // node: Node
16                //              a node (or node's id) to be moved
17                // e: Event
18                //              a mouse event, which started the move;
19                //              only pageX and pageY properties are used
20                // host: Object?
21                //              object which implements the functionality of the move,
22                //              and defines proper events (onMoveStart and onMoveStop)
23                this.node = dom.byId(node);
24                this.marginBox = {l: e.pageX, t: e.pageY};
25                this.mouseButton = e.button;
26                var h = (this.host = host), d = node.ownerDocument;
27
28                function stopEvent(e){
29                        e.preventDefault();
30                        e.stopPropagation();
31                }
32
33                this.events = [
34                        // At the start of a drag, onFirstMove is called, and then the following
35                        // listener is disconnected.
36                        on(d, touch.move, lang.hitch(this, "onFirstMove")),
37
38                        // These are called continually during the drag
39                        on(d, touch.move, lang.hitch(this, "onMouseMove")),
40
41                        // And these are called at the end of the drag
42                        on(d, touch.release,  lang.hitch(this, "onMouseUp")),
43
44                        // cancel text selection and text dragging
45                        on(d, "dragstart",   stopEvent),
46                        on(d.body, "selectstart", stopEvent)
47                ];
48
49                // Tell autoscroll that a drag is starting
50                autoscroll.autoScrollStart(d);
51
52                // notify that the move has started
53                if(h && h.onMoveStart){
54                        h.onMoveStart(this);
55                }
56        },
57        // mouse event processors
58        onMouseMove: function(e){
59                // summary:
60                //              event processor for onmousemove/ontouchmove
61                // e: Event
62                //              mouse/touch event
63                autoscroll.autoScroll(e);
64                var m = this.marginBox;
65                this.host.onMove(this, {l: m.l + e.pageX, t: m.t + e.pageY}, e);
66                e.preventDefault();
67                e.stopPropagation();
68        },
69        onMouseUp: function(e){
70                if(has("webkit") && has("mac") && this.mouseButton == 2 ?
71                                e.button == 0 : this.mouseButton == e.button){ // TODO Should condition be met for touch devices, too?
72                        this.destroy();
73                }
74                e.preventDefault();
75                e.stopPropagation();
76        },
77        // utilities
78        onFirstMove: function(e){
79                // summary:
80                //              makes the node absolute; it is meant to be called only once.
81                //              relative and absolutely positioned nodes are assumed to use pixel units
82                var s = this.node.style, l, t, h = this.host;
83                switch(s.position){
84                        case "relative":
85                        case "absolute":
86                                // assume that left and top values are in pixels already
87                                l = Math.round(parseFloat(s.left)) || 0;
88                                t = Math.round(parseFloat(s.top)) || 0;
89                                break;
90                        default:
91                                s.position = "absolute";        // enforcing the absolute mode
92                                var m = domGeom.getMarginBox(this.node);
93                                // event.pageX/pageY (which we used to generate the initial
94                                // margin box) includes padding and margin set on the body.
95                                // However, setting the node's position to absolute and then
96                                // doing domGeom.marginBox on it *doesn't* take that additional
97                                // space into account - so we need to subtract the combined
98                                // padding and margin.  We use getComputedStyle and
99                                // _getMarginBox/_getContentBox to avoid the extra lookup of
100                                // the computed style.
101                                var b = win.doc.body;
102                                var bs = domStyle.getComputedStyle(b);
103                                var bm = domGeom.getMarginBox(b, bs);
104                                var bc = domGeom.getContentBox(b, bs);
105                                l = m.l - (bc.l - bm.l);
106                                t = m.t - (bc.t - bm.t);
107                                break;
108                }
109                this.marginBox.l = l - this.marginBox.l;
110                this.marginBox.t = t - this.marginBox.t;
111                if(h && h.onFirstMove){
112                        h.onFirstMove(this, e);
113                }
114
115                // Disconnect touch.move that call this function
116                this.events.shift().remove();
117        },
118        destroy: function(){
119                // summary:
120                //              stops the move, deletes all references, so the object can be garbage-collected
121                array.forEach(this.events, function(handle){ handle.remove(); });
122                // undo global settings
123                var h = this.host;
124                if(h && h.onMoveStop){
125                        h.onMoveStop(this);
126                }
127                // destroy objects
128                this.events = this.node = this.host = null;
129        }
130});
131
132});
Note: See TracBrowser for help on using the repository browser.