if(!dojo._hasResource["dojo.dnd.Moveable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. dojo._hasResource["dojo.dnd.Moveable"] = true; dojo.provide("dojo.dnd.Moveable"); dojo.require("dojo.dnd.Mover"); dojo.declare("dojo.dnd.Moveable", null, { // object attributes (for markup) handle: "", delay: 0, skip: false, constructor: function(node, params){ // summary: an object, which makes a node moveable // node: Node: a node (or node's id) to be moved // params: Object: an optional object with additional parameters; // following parameters are recognized: // handle: Node: a node (or node's id), which is used as a mouse handle // if omitted, the node itself is used as a handle // delay: Number: delay move by this number of pixels // skip: Boolean: skip move of form elements // mover: Object: a constructor of custom Mover this.node = dojo.byId(node); if(!params){ params = {}; } this.handle = params.handle ? dojo.byId(params.handle) : null; if(!this.handle){ this.handle = this.node; } this.delay = params.delay > 0 ? params.delay : 0; this.skip = params.skip; this.mover = params.mover ? params.mover : dojo.dnd.Mover; this.events = [ dojo.connect(this.handle, "onmousedown", this, "onMouseDown"), // cancel text selection and text dragging dojo.connect(this.handle, "ondragstart", this, "onSelectStart"), dojo.connect(this.handle, "onselectstart", this, "onSelectStart") ]; }, // markup methods markupFactory: function(params, node){ return new dojo.dnd.Moveable(node, params); }, // methods destroy: function(){ // summary: stops watching for possible move, deletes all references, so the object can be garbage-collected dojo.forEach(this.events, dojo.disconnect); this.events = this.node = this.handle = null; }, // mouse event processors onMouseDown: function(e){ // summary: event processor for onmousedown, creates a Mover for the node // e: Event: mouse event if(this.skip && dojo.dnd.isFormElement(e)){ return; } if(this.delay){ this.events.push(dojo.connect(this.handle, "onmousemove", this, "onMouseMove")); this.events.push(dojo.connect(this.handle, "onmouseup", this, "onMouseUp")); this._lastX = e.pageX; this._lastY = e.pageY; }else{ new this.mover(this.node, e, this); } dojo.stopEvent(e); }, onMouseMove: function(e){ // summary: event processor for onmousemove, used only for delayed drags // e: Event: mouse event if(Math.abs(e.pageX - this._lastX) > this.delay || Math.abs(e.pageY - this._lastY) > this.delay){ this.onMouseUp(e); new this.mover(this.node, e, this); } dojo.stopEvent(e); }, onMouseUp: function(e){ // summary: event processor for onmouseup, used only for delayed delayed drags // e: Event: mouse event dojo.disconnect(this.events.pop()); dojo.disconnect(this.events.pop()); }, onSelectStart: function(e){ // summary: event processor for onselectevent and ondragevent // e: Event: mouse event if(!this.skip || !dojo.dnd.isFormElement(e)){ dojo.stopEvent(e); } }, // local events onMoveStart: function(/* dojo.dnd.Mover */ mover){ // summary: called before every move operation dojo.publish("/dnd/move/start", [mover]); dojo.addClass(dojo.body(), "dojoMove"); dojo.addClass(this.node, "dojoMoveItem"); }, onMoveStop: function(/* dojo.dnd.Mover */ mover){ // summary: called after every move operation dojo.publish("/dnd/move/stop", [mover]); dojo.removeClass(dojo.body(), "dojoMove"); dojo.removeClass(this.node, "dojoMoveItem"); }, onFirstMove: function(/* dojo.dnd.Mover */ mover){ // summary: called during the very first move notification, // can be used to initialize coordinates, can be overwritten. // default implementation does nothing }, onMove: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){ // summary: called during every move notification, // should actually move the node, can be overwritten. this.onMoving(mover, leftTop); var s = mover.node.style; s.left = leftTop.l + "px"; s.top = leftTop.t + "px"; this.onMoved(mover, leftTop); }, onMoving: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){ // summary: called before every incremental move, // can be overwritten. // default implementation does nothing }, onMoved: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){ // summary: called after every incremental move, // can be overwritten. // default implementation does nothing } }); }