UNPKG

dojo

Version:

Dojo core is a powerful, lightweight library that makes common tasks quicker and easier. Animate elements, manipulate the DOM, and query with easy CSS syntax, all without sacrificing performance.

212 lines (192 loc) 5.9 kB
define([ "../_base/array", "../_base/declare", "../_base/lang", "../dom", "../dom-class", "../Evented", "../has", "../on", "../topic", "../touch", "./common", "./Mover", "../_base/window" ], function(array, declare, lang, dom, domClass, Evented, has, on, topic, touch, dnd, Mover, win){ // module: // dojo/dnd/Moveable var touchActionPropertyName; var setTouchAction = function () {}; function setTouchActionPropertyName() { if ("touchAction" in document.body.style) { touchActionPropertyName = "touchAction"; } else if ("msTouchAction" in document.body.style) { touchActionPropertyName = "msTouchAction"; } setTouchAction = function setTouchAction(/* Node */ node, /* string */ action) { node.style[touchActionPropertyName] = action; } setTouchAction(arguments[0], arguments[1]); } if (has("touch-action")) { // Ensure that the logic to determine "touchActionPropertyName" runs setTouchAction = setTouchActionPropertyName; } var Moveable = declare("dojo.dnd.Moveable", [Evented], { // summary: // an object, which makes a node movable // object attributes (for markup) handle: "", delay: 0, skip: false, constructor: function(node, params){ // node: Node // a node (or node's id) to be moved // params: Moveable.__MoveableArgs? // optional parameters this.node = dom.byId(node); setTouchAction(this.node, "none"); if(!params){ params = {}; } this.handle = params.handle ? dom.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 : Mover; this.events = [ on(this.handle, touch.press, lang.hitch(this, "onMouseDown")), // cancel text selection and text dragging on(this.handle, "dragstart", lang.hitch(this, "onSelectStart")), on(this.handle, "selectstart", lang.hitch(this, "onSelectStart")) ]; }, // markup methods markupFactory: function(params, node, Ctor){ return new Ctor(node, params); }, // methods destroy: function(){ // summary: // stops watching for possible move, deletes all references, so the object can be garbage-collected array.forEach(this.events, function(handle){ handle.remove(); }); setTouchAction(this.node, ""); this.events = this.node = this.handle = null; }, // mouse event processors onMouseDown: function(e){ // summary: // event processor for onmousedown/ontouchstart, creates a Mover for the node // e: Event // mouse/touch event if(this.skip && dnd.isFormElement(e)){ return; } if(this.delay){ this.events.push( on(this.handle, touch.move, lang.hitch(this, "onMouseMove")), on(this.handle.ownerDocument, touch.release, lang.hitch(this, "onMouseUp")) ); this._lastX = e.pageX; this._lastY = e.pageY; }else{ this.onDragDetected(e); } e.stopPropagation(); e.preventDefault(); }, onMouseMove: function(e){ // summary: // event processor for onmousemove/ontouchmove, used only for delayed drags // e: Event // mouse/touch event if(Math.abs(e.pageX - this._lastX) > this.delay || Math.abs(e.pageY - this._lastY) > this.delay){ this.onMouseUp(e); this.onDragDetected(e); } e.stopPropagation(); e.preventDefault(); }, onMouseUp: function(e){ // summary: // event processor for onmouseup, used only for delayed drags // e: Event // mouse event for(var i = 0; i < 2; ++i){ this.events.pop().remove(); } e.stopPropagation(); e.preventDefault(); }, onSelectStart: function(e){ // summary: // event processor for onselectevent and ondragevent // e: Event // mouse event if(!this.skip || !dnd.isFormElement(e)){ e.stopPropagation(); e.preventDefault(); } }, // local events onDragDetected: function(/*Event*/ e){ // summary: // called when the drag is detected; // responsible for creation of the mover new this.mover(this.node, e, this); }, onMoveStart: function(/*Mover*/ mover){ // summary: // called before every move operation topic.publish("/dnd/move/start", mover); domClass.add(win.body(), "dojoMove"); domClass.add(this.node, "dojoMoveItem"); }, onMoveStop: function(/*Mover*/ mover){ // summary: // called after every move operation topic.publish("/dnd/move/stop", mover); domClass.remove(win.body(), "dojoMove"); domClass.remove(this.node, "dojoMoveItem"); }, onFirstMove: function(/*===== mover, e =====*/){ // summary: // called during the very first move notification; // can be used to initialize coordinates, can be overwritten. // mover: Mover // e: Event // default implementation does nothing }, onMove: function(mover, leftTop /*=====, e =====*/){ // summary: // called during every move notification; // should actually move the node; can be overwritten. // mover: Mover // leftTop: Object // e: Event 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(/*===== mover, leftTop =====*/){ // summary: // called before every incremental move; can be overwritten. // mover: Mover // leftTop: Object // default implementation does nothing }, onMoved: function(/*===== mover, leftTop =====*/){ // summary: // called after every incremental move; can be overwritten. // mover: Mover // leftTop: Object // default implementation does nothing } }); /*===== Moveable.__MoveableArgs = declare([], { // handle: Node||String // A node (or node's id), which is used as a mouse handle. // If omitted, the node itself is used as a handle. handle: null, // delay: Number // delay move by this number of pixels delay: 0, // skip: Boolean // skip move of form elements skip: false, // mover: Object // a constructor of custom Mover mover: dnd.Mover }); =====*/ return Moveable; });