2 Copyright (c) 2004-2010, 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
8 if(!dojo._hasResource["dojo.dnd.Mover"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
9 dojo._hasResource["dojo.dnd.Mover"] = true;
10 dojo.provide("dojo.dnd.Mover");
12 dojo.require("dojo.dnd.common");
13 dojo.require("dojo.dnd.autoscroll");
15 dojo.declare("dojo.dnd.Mover", null, {
16 constructor: function(node, e, host){
18 // an object, which makes a node follow the mouse.
19 // Used as a default mover, and as a base class for custom movers.
21 // a node (or node's id) to be moved
23 // a mouse event, which started the move;
24 // only pageX and pageY properties are used
26 // object which implements the functionality of the move,
27 // and defines proper events (onMoveStart and onMoveStop)
28 this.node = dojo.byId(node);
29 this.marginBox = {l: e.pageX, t: e.pageY};
30 this.mouseButton = e.button;
31 var h = this.host = host, d = node.ownerDocument,
32 firstEvent = dojo.connect(d, "onmousemove", this, "onFirstMove");
34 dojo.connect(d, "onmousemove", this, "onMouseMove"),
35 dojo.connect(d, "onmouseup", this, "onMouseUp"),
36 // cancel text selection and text dragging
37 dojo.connect(d, "ondragstart", dojo.stopEvent),
38 dojo.connect(d.body, "onselectstart", dojo.stopEvent),
41 // notify that the move has started
42 if(h && h.onMoveStart){
46 // mouse event processors
47 onMouseMove: function(e){
49 // event processor for onmousemove
52 dojo.dnd.autoScroll(e);
53 var m = this.marginBox;
54 this.host.onMove(this, {l: m.l + e.pageX, t: m.t + e.pageY}, e);
57 onMouseUp: function(e){
58 if(dojo.isWebKit && dojo.isMac && this.mouseButton == 2 ?
59 e.button == 0 : this.mouseButton == e.button){
65 onFirstMove: function(e){
67 // makes the node absolute; it is meant to be called only once.
68 // relative and absolutely positioned nodes are assumed to use pixel units
69 var s = this.node.style, l, t, h = this.host;
73 // assume that left and top values are in pixels already
74 l = Math.round(parseFloat(s.left)) || 0;
75 t = Math.round(parseFloat(s.top)) || 0;
78 s.position = "absolute"; // enforcing the absolute mode
79 var m = dojo.marginBox(this.node);
80 // event.pageX/pageY (which we used to generate the initial
81 // margin box) includes padding and margin set on the body.
82 // However, setting the node's position to absolute and then
83 // doing dojo.marginBox on it *doesn't* take that additional
84 // space into account - so we need to subtract the combined
85 // padding and margin. We use getComputedStyle and
86 // _getMarginBox/_getContentBox to avoid the extra lookup of
87 // the computed style.
88 var b = dojo.doc.body;
89 var bs = dojo.getComputedStyle(b);
90 var bm = dojo._getMarginBox(b, bs);
91 var bc = dojo._getContentBox(b, bs);
92 l = m.l - (bc.l - bm.l);
93 t = m.t - (bc.t - bm.t);
96 this.marginBox.l = l - this.marginBox.l;
97 this.marginBox.t = t - this.marginBox.t;
98 if(h && h.onFirstMove){
99 h.onFirstMove(this, e);
101 dojo.disconnect(this.events.pop());
105 // stops the move, deletes all references, so the object can be garbage-collected
106 dojo.forEach(this.events, dojo.disconnect);
107 // undo global settings
109 if(h && h.onMoveStop){
113 this.events = this.node = this.host = null;