mirror of
				https://git.tt-rss.org/fox/tt-rss.git
				synced 2025-10-26 02:11:16 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			125 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| define("dojo/dnd/Mover", [
 | |
| 	"../_base/array", "../_base/declare", "../_base/event", "../_base/lang", "../sniff", "../_base/window",
 | |
| 	"../dom", "../dom-geometry", "../dom-style", "../Evented", "../on", "../touch", "./common", "./autoscroll"
 | |
| ], function(array, declare, event, lang, has, win, dom, domGeom, domStyle, Evented, on, touch, dnd, autoscroll){
 | |
| 
 | |
| // module:
 | |
| //		dojo/dnd/Mover
 | |
| 
 | |
| return declare("dojo.dnd.Mover", [Evented], {
 | |
| 	// summary:
 | |
| 	//		an object which makes a node follow the mouse, or touch-drag on touch devices.
 | |
| 	//		Used as a default mover, and as a base class for custom movers.
 | |
| 
 | |
| 	constructor: function(node, e, host){
 | |
| 		// node: Node
 | |
| 		//		a node (or node's id) to be moved
 | |
| 		// e: Event
 | |
| 		//		a mouse event, which started the move;
 | |
| 		//		only pageX and pageY properties are used
 | |
| 		// host: Object?
 | |
| 		//		object which implements the functionality of the move,
 | |
| 		//	 	and defines proper events (onMoveStart and onMoveStop)
 | |
| 		this.node = dom.byId(node);
 | |
| 		this.marginBox = {l: e.pageX, t: e.pageY};
 | |
| 		this.mouseButton = e.button;
 | |
| 		var h = (this.host = host), d = node.ownerDocument;
 | |
| 		this.events = [
 | |
| 			// At the start of a drag, onFirstMove is called, and then the following
 | |
| 			// listener is disconnected.
 | |
| 			on(d, touch.move, lang.hitch(this, "onFirstMove")),
 | |
| 
 | |
| 			// These are called continually during the drag
 | |
| 			on(d, touch.move, lang.hitch(this, "onMouseMove")),
 | |
| 
 | |
| 			// And these are called at the end of the drag
 | |
| 			on(d, touch.release,  lang.hitch(this, "onMouseUp")),
 | |
| 
 | |
| 			// cancel text selection and text dragging
 | |
| 			on(d, "dragstart",   event.stop),
 | |
| 			on(d.body, "selectstart", event.stop)
 | |
| 		];
 | |
| 
 | |
| 		// Tell autoscroll that a drag is starting
 | |
| 		autoscroll.autoScrollStart(d);
 | |
| 
 | |
| 		// notify that the move has started
 | |
| 		if(h && h.onMoveStart){
 | |
| 			h.onMoveStart(this);
 | |
| 		}
 | |
| 	},
 | |
| 	// mouse event processors
 | |
| 	onMouseMove: function(e){
 | |
| 		// summary:
 | |
| 		//		event processor for onmousemove/ontouchmove
 | |
| 		// e: Event
 | |
| 		//		mouse/touch event
 | |
| 		autoscroll.autoScroll(e);
 | |
| 		var m = this.marginBox;
 | |
| 		this.host.onMove(this, {l: m.l + e.pageX, t: m.t + e.pageY}, e);
 | |
| 		event.stop(e);
 | |
| 	},
 | |
| 	onMouseUp: function(e){
 | |
| 		if(has("webkit") && has("mac") && this.mouseButton == 2 ?
 | |
| 				e.button == 0 : this.mouseButton == e.button){ // TODO Should condition be met for touch devices, too?
 | |
| 			this.destroy();
 | |
| 		}
 | |
| 		event.stop(e);
 | |
| 	},
 | |
| 	// utilities
 | |
| 	onFirstMove: function(e){
 | |
| 		// summary:
 | |
| 		//		makes the node absolute; it is meant to be called only once.
 | |
| 		//		relative and absolutely positioned nodes are assumed to use pixel units
 | |
| 		var s = this.node.style, l, t, h = this.host;
 | |
| 		switch(s.position){
 | |
| 			case "relative":
 | |
| 			case "absolute":
 | |
| 				// assume that left and top values are in pixels already
 | |
| 				l = Math.round(parseFloat(s.left)) || 0;
 | |
| 				t = Math.round(parseFloat(s.top)) || 0;
 | |
| 				break;
 | |
| 			default:
 | |
| 				s.position = "absolute";	// enforcing the absolute mode
 | |
| 				var m = domGeom.getMarginBox(this.node);
 | |
| 				// event.pageX/pageY (which we used to generate the initial
 | |
| 				// margin box) includes padding and margin set on the body.
 | |
| 				// However, setting the node's position to absolute and then
 | |
| 				// doing domGeom.marginBox on it *doesn't* take that additional
 | |
| 				// space into account - so we need to subtract the combined
 | |
| 				// padding and margin.  We use getComputedStyle and
 | |
| 				// _getMarginBox/_getContentBox to avoid the extra lookup of
 | |
| 				// the computed style.
 | |
| 				var b = win.doc.body;
 | |
| 				var bs = domStyle.getComputedStyle(b);
 | |
| 				var bm = domGeom.getMarginBox(b, bs);
 | |
| 				var bc = domGeom.getContentBox(b, bs);
 | |
| 				l = m.l - (bc.l - bm.l);
 | |
| 				t = m.t - (bc.t - bm.t);
 | |
| 				break;
 | |
| 		}
 | |
| 		this.marginBox.l = l - this.marginBox.l;
 | |
| 		this.marginBox.t = t - this.marginBox.t;
 | |
| 		if(h && h.onFirstMove){
 | |
| 			h.onFirstMove(this, e);
 | |
| 		}
 | |
| 
 | |
| 		// Disconnect touch.move that call this function
 | |
| 		this.events.shift().remove();
 | |
| 	},
 | |
| 	destroy: function(){
 | |
| 		// summary:
 | |
| 		//		stops the move, deletes all references, so the object can be garbage-collected
 | |
| 		array.forEach(this.events, function(handle){ handle.remove(); });
 | |
| 		// undo global settings
 | |
| 		var h = this.host;
 | |
| 		if(h && h.onMoveStop){
 | |
| 			h.onMoveStop(this);
 | |
| 		}
 | |
| 		// destroy objects
 | |
| 		this.events = this.node = this.host = null;
 | |
| 	}
 | |
| });
 | |
| 
 | |
| });
 |